/*!
 * 
 * Angle - Bootstrap Admin App + AngularJS
 * 
 * Author: @themicon_co
 * Website: http://themicon.co
 * License: http://support.wrapbootstrap.com/knowledge_base/topics/usage-licenses
 * 
 */

if (typeof $ === 'undefined') { throw new Error('This application\'s JavaScript requires jQuery'); }

// APP START
// ----------------------------------- 

var App = angular.module('angle', [
    'ngRoute',
    'ngAnimate',
    'ngStorage',
    'ngCookies',
    'pascalprecht.translate',
    'ui.bootstrap',
    'ui.router',
    'oc.lazyLoad',
    'cfp.loadingBar',
    'ngSanitize',
    'ngResource',
    'tmh.dynamicLocale',
    'ui.utils'
  ]);

App.run(["$rootScope", "$state", "$stateParams",  '$window', '$templateCache', function ($rootScope, $state, $stateParams, $window, $templateCache) {
  // Set reference to access them from any scope
  $rootScope.$state = $state;
  $rootScope.$stateParams = $stateParams;
  $rootScope.$storage = $window.localStorage;

  // Uncomment this to disable template cache
  /*$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
      if (typeof(toState) !== 'undefined'){
        $templateCache.remove(toState.templateUrl);
      }
  });*/

  // Scope Globals
  // ----------------------------------- 
  $rootScope.app = {
    name: 'Angle',
    description: 'Angular Bootstrap Admin Template',
    year: ((new Date()).getFullYear()),
    layout: {
      isFixed: true,
      isCollapsed: false,
      isBoxed: false,
      isRTL: false,
      horizontal: false,
      isFloat: false,
      asideHover: false,
      theme: null
    },
    useFullLayout: false,
    hiddenFooter: false,
    viewAnimation: 'ng-fadeInUp'
  };
 // $rootScope.user = {
    
 // };

}]);

/**=========================================================
 * Module: config.js
 * App routes and resources configuration
 =========================================================*/

App.config(['$stateProvider', '$locationProvider', '$urlRouterProvider', 'RouteHelpersProvider',
function ($stateProvider, $locationProvider, $urlRouterProvider, helper) {
  'use strict';

  // Set the following to true to enable the HTML5 Mode
  // You may have to set <base> tag in index and a routing configuration in your server
  $locationProvider.html5Mode(false);

  // defaults to dashboard
  $urlRouterProvider.otherwise('/app-h/home');

  // 
  // Application Routes
  // -----------------------------------   
  $stateProvider
    .state('app', {
        url: '/app',
        abstract: true,
        templateUrl: helper.basepath('app.html'),
        controller: 'AppController',
        resolve: helper.resolveFor('fastclick', 'modernizr', 'icons', 'screenfull', 'animo', 'sparklines', 'slimscroll', 'classyloader', 'toaster', 'whirl')
    })
    .state('app.password', {
        url: '/password',
        title: 'Password',
        templateUrl: helper.basepath('password.html'),
        resolve: helper.resolveFor('flot-chart','flot-chart-plugins')
    })
    .state('app.form-imagecrop', {
        url: '/form/imagecrop',
        templateUrl: helper.basepath('form-imagecrop.html'),
        resolve: helper.resolveFor('ngImgCrop', 'filestyle')
    })
    .state('app.fileList', {
        url: '/file/list/:projectfileName',
        templateUrl: helper.basepath('fileList.html'),
        resolve: helper.resolveFor('xeditable','localytics.directives',
          'datatables','ui.grid','angularFileUpload', 'ngDialog','filestyle','angularBootstrapNavTree')
        
    })
    .state('app.fileIcon', {
        url: '/file/icon/:projectfileName',
        templateUrl: helper.basepath('fileIcon.html'),
        resolve: helper.resolveFor('xeditable','localytics.directives','datatables','ui.grid',
          'angularFileUpload', 'filestyle','angularBootstrapNavTree','ui.select','ngDialog')
        
    })
    .state('app.projectList', {
        url: '/project/list/:perTypeName',
        templateUrl: helper.basepath('projectList.html'),
        resolve: helper.resolveFor('xeditable','localytics.directives',
          'datatables','ui.grid','angularFileUpload', 'filestyle','ui.select','ngDialog')
    })
    .state('app.programs', {
        url: '/programs',
        templateUrl: helper.basepath('programs.html'),
        resolve: helper.resolveFor('xeditable','localytics.directives',
          'datatables','ui.grid','angularFileUpload', 'filestyle','ngDialog')
    })
    .state('app.projectIcon', {
        url: '/project/icon/:perTypeName',
        templateUrl: helper.basepath('projectIcon.html'),
         resolve: helper.resolveFor('morris','xeditable','localytics.directives',
          'datatables','ui.grid','angularFileUpload', 
          'filestyle','ui.select','ngDialog')
    
    })
    .state('app.fileView', {
        url: '/file/view',
        templateUrl: helper.basepath('fileView.html'),
        resolve: {
            deps: helper.resolveFor('ngWig','codemirror', 'ui.codemirror', 'codemirror-modes-web', 
              'angularBootstrapNavTree',
              'ngImgCrop', 'filestyle','xeditable','localytics.directives',
              'datatables','ui.grid','angularFileUpload','ui.select','ngDialog').deps,
            filetree: ["LoadTreeService", function (LoadTreeService) {
                return LoadTreeService.get().$promise.then(function (res) {
                    return res.data;
                });
            }]
        },
        controller: ["$rootScope", "$scope", "filetree", function($rootScope, $scope, filetree) {
            // Set the tree data into the scope
            $scope.filetree_data = filetree;
            // Setup the layout mode 
            $rootScope.app.useFullLayout = true;
            $rootScope.app.hiddenFooter = true;
            $rootScope.app.layout.isCollapsed = true;
            // Restore layout
            $scope.$on('$destroy', function(){
                $rootScope.app.useFullLayout = false;
                $rootScope.app.hiddenFooter = false;
            });
        }]
    })
    .state('page', {
        url: '/page',
        templateUrl: 'app/pages/page.html',
        resolve: helper.resolveFor('modernizr', 'icons'),
        controller: ["$rootScope", function($rootScope) {
            $rootScope.app.layout.isBoxed = false;
        }]
    })
    .state('page.login', {
        url: '/login',
        title: "Login",
        templateUrl: 'app/pages/login.html'
    })
    .state('page.register', {
        url: '/register',
        title: "Register",
        templateUrl: 'app/pages/register.html'
    })
    .state('app-h', {
        url: '/app-h',
        abstract: true,
        templateUrl: helper.basepath( 'app-h.html' ),
        controller: 'AppController',
        resolve: helper.resolveFor('fastclick','chartjs', 
          'modernizr', 'icons', 'screenfull', 'animo',
           'sparklines', 'slimscroll', 'classyloader', 
           'toaster', 'whirl')
    })
    .state('app-h.home', {
        url: '/home',
        title: 'Home',
        templateUrl: helper.basepath('home.html'),
        controller: ["$rootScope", "$scope", function($rootScope, $scope) {
            $rootScope.app.layout.horizontal = true;
            $scope.$on('$destroy', function(){
                $rootScope.app.layout.horizontal = false;
            });
        }],
        resolve: helper.resolveFor('flot-chart',"ngSanitize",'fullease','fullpage',
            'com.2fdevs.videogular',
            'com.2fdevs.videogular.plugins.controls',
            'com.2fdevs.videogular.plugins.overlayplay',
            'com.2fdevs.videogular.plugins.poster',
            'com.2fdevs.videogular.plugins.buffering','chartjs','spinkit', 'akoenig.deckgrid','morris','flot-chart-plugins')
    })
    .state('app-h.list', {
        url: '/list',
        title: 'List',
        templateUrl: helper.basepath('list.html'),
        controller: ["$rootScope", "$scope", function($rootScope, $scope) {
            $rootScope.app.layout.horizontal = true;
            $scope.$on('$destroy', function(){
                $rootScope.app.layout.horizontal = false;
            });
        }],
        resolve: helper.resolveFor('flot-chart','ng-nestable','ui.select',
          'chartjs','spinkit', 'akoenig.deckgrid','morris',
          'flot-chart-plugins','xeditable','localytics.directives','datatables','ui.grid',
          'angularFileUpload', 'filestyle','angularBootstrapNavTree','spinkit', 'akoenig.deckgrid','datatables')
    })
    .state('app-h.datatable', {
        url: '/datatable/:typeName',
        title: 'Datatable',
        templateUrl: helper.basepath('datatable.html'),
        controller: ["$rootScope", "$scope", function($rootScope, $scope) {
            $rootScope.app.layout.horizontal = true;
            $scope.$on('$destroy', function(){
                $rootScope.app.layout.horizontal = false;
            });
        }],
        resolve: helper.resolveFor('flot-chart','ng-nestable','ui.select',
          'chartjs','spinkit', 'akoenig.deckgrid','morris',
          'flot-chart-plugins','xeditable','localytics.directives','datatables','ui.grid',
          'angularFileUpload', 'filestyle','angularBootstrapNavTree','spinkit', 'akoenig.deckgrid','datatables','angular-drag')
    })
    .state('app-h.dataList', {
        url: '/dataList/:typeName',
        title: 'DataList',
        templateUrl: helper.basepath('dataList.html'),
        controller: ["$rootScope", "$scope", function($rootScope, $scope) {
            $rootScope.app.layout.horizontal = true;
            $scope.$on('$destroy', function(){
                $rootScope.app.layout.horizontal = false;
            });
        }],
        resolve: helper.resolveFor('flot-chart','ng-nestable','ui.select',
          'chartjs','spinkit', 'akoenig.deckgrid','morris',
          'flot-chart-plugins','xeditable','localytics.directives','datatables','ui.grid',
          'angularFileUpload', 'filestyle','angularBootstrapNavTree','spinkit', 'akoenig.deckgrid','datatables','angular-drag')
    })
    .state('app-h.detail', {
        url: '/datatable/:typeName/:projectName',
        title: 'Detail',
        templateUrl: helper.basepath('detail.html'),
        controller: ["$rootScope", "$scope", function($rootScope, $scope) {
            $rootScope.app.layout.horizontal = true;
            $scope.$on('$destroy', function(){
                $rootScope.app.layout.horizontal = false;
            });
        }],
        resolve: helper.resolveFor('flot-chart','ng-nestable','ui.select',
          'chartjs','spinkit', 'akoenig.deckgrid','morris',
          'flot-chart-plugins','xeditable','localytics.directives','datatables','ui.grid',
          'angularFileUpload', 'filestyle','angularBootstrapNavTree','spinkit', 'akoenig.deckgrid','datatables')
    })
    // 
    // Single Page Routes
    // ----------------------------------- 
    
   
    // 
    // CUSTOM RESOLVES
    //   Add your own resolves properties
    //   following this object extend
    //   method
    // ----------------------------------- 
    // .state('app.someroute', {
    //   url: '/some_url',
    //   templateUrl: 'path_to_template.html',
    //   controller: 'someController',
    //   resolve: angular.extend(
    //     helper.resolveFor(), {
    //     // YOUR RESOLVES GO HERE
    //     }
    //   )
    // })
    ;


}]).config(['$ocLazyLoadProvider', 'APP_REQUIRES', function ($ocLazyLoadProvider, APP_REQUIRES) {
    'use strict';

    // Lazy Load modules configuration
    $ocLazyLoadProvider.config({
      debug: false,
      events: true,
      modules: APP_REQUIRES.modules
    });

}]).config(['$controllerProvider', '$compileProvider', '$filterProvider', '$provide',
    function ( $controllerProvider, $compileProvider, $filterProvider, $provide) {
      'use strict';
      // registering components after bootstrap
      App.controller = $controllerProvider.register;
      App.directive  = $compileProvider.directive;
      App.filter     = $filterProvider.register;
      App.factory    = $provide.factory;
      App.service    = $provide.service;
      App.constant   = $provide.constant;
      App.value      = $provide.value;

}]).config(['$translateProvider', function ($translateProvider) {

    $translateProvider.useStaticFilesLoader({
        prefix : 'app/i18n/',
        suffix : '.json'
    });
    $translateProvider.preferredLanguage('en');
    $translateProvider.useLocalStorage();
    $translateProvider.usePostCompiling(true);

}]).config(['tmhDynamicLocaleProvider', function (tmhDynamicLocaleProvider) {

    tmhDynamicLocaleProvider.localeLocationPattern('vendor/angular-i18n/angular-locale_{{locale}}.js');

    // tmhDynamicLocaleProvider.useStorage('$cookieStore');

}]).config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {

    cfpLoadingBarProvider.includeBar = true;
    cfpLoadingBarProvider.includeSpinner = false;
    cfpLoadingBarProvider.latencyThreshold = 500;
    cfpLoadingBarProvider.parentSelector = '.wrapper > section';

}]).config(['$tooltipProvider', function ($tooltipProvider) {

    $tooltipProvider.options({appendToBody: true});

}]).config(['$httpProvider', function($httpProvider) {
     $httpProvider.defaults.xsrfCookieName = 'csrftoken';
     $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);

/**=========================================================
 * Module: constants.js
 * Define constants to inject across the application
 =========================================================*/
App
  .constant('APP_COLORS', {
    'primary':                '#5d9cec',
    'success':                '#27c24c',
    'info':                   '#23b7e5',
    'warning':                '#ff902b',
    'danger':                 '#f05050',
    'inverse':                '#131e26',
    'green':                  '#37bc9b',
    'pink':                   '#f532e5',
    'purple':                 '#7266ba',
    'dark':                   '#3a3f51',
    'yellow':                 '#fad732',
    'gray-darker':            '#232735',
    'gray-dark':              '#3a3f51',
    'gray':                   '#dde6e9',
    'gray-light':             '#e4eaec',
    'gray-lighter':           '#edf1f2'
  })
  .constant('APP_MEDIAQUERY', {
    'desktopLG':             1200,
    'desktop':                992,
    'tablet':                 768,
    'mobile':                 480
  })
  .constant('APP_REQUIRES', {
    // jQuery based and standalone scripts
    scripts: {
      'whirl':              ['vendor/whirl/dist/whirl.css'],
      'classyloader':       ['vendor/jquery-classyloader/js/jquery.classyloader.min.js'],
      'animo':              ['vendor/animo.js/animo.js'],
      'fastclick':          ['vendor/fastclick/lib/fastclick.js'],
      'modernizr':          ['vendor/modernizr/modernizr.js'],
      'animate':            ['vendor/animate.css/animate.min.css'],
      'icons':              ['vendor/skycons/skycons.js',
                             'vendor/fontawesome/css/font-awesome.min.css',
                             'vendor/simple-line-icons/css/simple-line-icons.css',
                             'vendor/weather-icons/css/weather-icons.min.css'],
      'sparklines':         ['app/vendor/sparklines/jquery.sparkline.min.js'],
      'wysiwyg':            ['vendor/bootstrap-wysiwyg/bootstrap-wysiwyg.js',
                             'vendor/bootstrap-wysiwyg/external/jquery.hotkeys.js'],
      'slimscroll':         ['vendor/slimScroll/jquery.slimscroll.min.js'],
      'screenfull':         ['vendor/screenfull/dist/screenfull.js'],
      'vector-map':         ['vendor/ika.jvectormap/jquery-jvectormap-1.2.2.min.js',
                             'vendor/ika.jvectormap/jquery-jvectormap-1.2.2.css'],
      'vector-map-maps':    ['vendor/ika.jvectormap/jquery-jvectormap-world-mill-en.js',
                             'vendor/ika.jvectormap/jquery-jvectormap-us-mill-en.js'],
      'loadGoogleMapsJS':   ['app/vendor/gmap/load-google-maps.js'],
      'flot-chart':         ['vendor/Flot/jquery.flot.js'],
      'flot-chart-plugins': ['vendor/flot.tooltip/js/jquery.flot.tooltip.min.js',
                             'vendor/Flot/jquery.flot.resize.js',
                             'vendor/Flot/jquery.flot.pie.js',
                             'vendor/Flot/jquery.flot.time.js',
                             'vendor/Flot/jquery.flot.categories.js',
                             'vendor/flot-spline/js/jquery.flot.spline.min.js'],
                            // jquery core and widgets
      'jquery-ui':          ['vendor/jquery-ui/ui/core.js',
                             'vendor/jquery-ui/ui/widget.js'],
                             // loads only jquery required modules and touch support
      'jquery-ui-widgets':  ['vendor/jquery-ui/ui/core.js',
                             'vendor/jquery-ui/ui/widget.js',
                             'vendor/jquery-ui/ui/mouse.js',
                             'vendor/jquery-ui/ui/draggable.js',
                             'vendor/jquery-ui/ui/droppable.js',
                             'vendor/jquery-ui/ui/sortable.js',
                             'vendor/jqueryui-touch-punch/jquery.ui.touch-punch.min.js'],
      'moment' :            ['vendor/moment/min/moment-with-locales.min.js'],
      'inputmask':          ['vendor/jquery.inputmask/dist/jquery.inputmask.bundle.min.js'],
      'flatdoc':            ['vendor/flatdoc/flatdoc.js'],
      'codemirror':         ['vendor/codemirror/lib/codemirror.js',
                             'vendor/codemirror/lib/codemirror.css'],
      // modes for common web files
      'codemirror-modes-web': ['vendor/codemirror/mode/javascript/javascript.js',
                               'vendor/codemirror/mode/xml/xml.js',
                               'vendor/codemirror/mode/htmlmixed/htmlmixed.js',
                               'vendor/codemirror/mode/css/css.js'],
      'taginput' :          ['vendor/bootstrap-tagsinput/dist/bootstrap-tagsinput.css',
                             'vendor/bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js'],
      'filestyle':          ['vendor/bootstrap-filestyle/src/bootstrap-filestyle.js'],
      'parsley':            ['vendor/parsleyjs/dist/parsley.min.js'],
      'fullcalendar':       ['vendor/fullcalendar/dist/fullcalendar.min.js',
                             'vendor/fullcalendar/dist/fullcalendar.css'],
      'gcal':               ['vendor/fullcalendar/dist/gcal.js'],
      'chartjs':            ['vendor/Chart.js/Chart.js'],
      'morris':             ['vendor/raphael/raphael.js',
                             'vendor/morris.js/morris.js',
                             'vendor/morris.js/morris.css'],
      'loaders.css':          ['vendor/loaders.css/loaders.css'],
      'spinkit':              ['vendor/spinkit/css/spinkit.css'],

      'ngSanitize':           ['vendor/angular-video/angular-sanitize.min.js'],
      'com.2fdevs.videogular':           ['vendor/angular-video/videogular.js'],
      'com.2fdevs.videogular.plugins.controls':           ['vendor/angular-video/vg-controls.js'],
      'com.2fdevs.videogular.plugins.overlayplay':           ['vendor/angular-video/vg-overlay-play.js'],
      'com.2fdevs.videogular.plugins.poster':           ['vendor/angular-video/vg-poster.js'],
      'com.2fdevs.videogular.plugins.buffering':           ['vendor/angular-video/vg-buffering.js'],
      
      'fullease':              ['vendor/fullpage/jquery.easing.min.js'],
      'fullpage':              ['vendor/fullpage/jquery.fullPage.min.js'],
      'angular-drag':                  ['vendor/angular-drag/angular-drag.js'],
      

    },
    // Angular based script (use the right module name)
    modules: [
      {name: 'toaster',                   files: ['vendor/angularjs-toaster/toaster.js',
                                                 'vendor/angularjs-toaster/toaster.css']},
      {name: 'localytics.directives',     files: ['vendor/chosen_v1.2.0/chosen.jquery.min.js',
                                                 'vendor/chosen_v1.2.0/chosen.min.css',
                                                 'vendor/angular-chosen-localytics/chosen.js']},
      {name: 'ngDialog',                  files: ['vendor/ngDialog/js/ngDialog.min.js',
                                                 'vendor/ngDialog/css/ngDialog.min.css',
                                                 'vendor/ngDialog/css/ngDialog-theme-default.min.css'] },
      {name: 'ngWig',                     files: ['vendor/ngWig/dist/ng-wig.min.js'] },
      {name: 'ngTable',                   files: ['vendor/ng-table/dist/ng-table.min.js',
                                                  'vendor/ng-table/dist/ng-table.min.css']},
      {name: 'ngTableExport',             files: ['vendor/ng-table-export/ng-table-export.js']},
      {name: 'angularBootstrapNavTree',   files: ['vendor/angular-bootstrap-nav-tree/dist/abn_tree_directive.js',
                                                  'vendor/angular-bootstrap-nav-tree/dist/abn_tree.css']},
      {name: 'htmlSortable',              files: ['vendor/html.sortable/dist/html.sortable.js',
                                                  'vendor/html.sortable/dist/html.sortable.angular.js']},
      {name: 'xeditable',                 files: ['vendor/angular-xeditable/dist/js/xeditable.js',
                                                  'vendor/angular-xeditable/dist/css/xeditable.css']},
      {name: 'angularFileUpload',         files: ['vendor/angular-file-upload/angular-file-upload.js']},
      {name: 'ngImgCrop',                 files: ['vendor/ng-img-crop/compile/unminified/ng-img-crop.js',
                                                  'vendor/ng-img-crop/compile/unminified/ng-img-crop.css']},
      {name: 'ui.select',                 files: ['vendor/angular-ui-select/dist/select.js',
                                                  'vendor/angular-ui-select/dist/select.css']},
      {name: 'ui.codemirror',             files: ['vendor/angular-ui-codemirror/ui-codemirror.js']},
      {name: 'angular-carousel',          files: ['vendor/angular-carousel/dist/angular-carousel.css',
                                                  'vendor/angular-carousel/dist/angular-carousel.js']},
      {name: 'ngGrid',                    files: ['vendor/ng-grid/build/ng-grid.min.js',
                                                  'vendor/ng-grid/ng-grid.css' ]},
      {name: 'infinite-scroll',           files: ['vendor/ngInfiniteScroll/build/ng-infinite-scroll.js']},
      {name: 'ui.bootstrap-slider',       files: ['vendor/seiyria-bootstrap-slider/dist/bootstrap-slider.min.js',
                                                  'vendor/seiyria-bootstrap-slider/dist/css/bootstrap-slider.min.css',
                                                  'vendor/angular-bootstrap-slider/slider.js']},
      {name: 'ui.grid',                   files: ['vendor/angular-ui-grid/ui-grid.min.css',
                                                  'vendor/angular-ui-grid/ui-grid.min.js']},
      {name: 'textAngularSetup',          files: ['vendor/textAngular/src/textAngularSetup.js']},
      {name: 'textAngular',               files: ['vendor/textAngular/dist/textAngular-rangy.min.js',
                                                  'vendor/textAngular/src/textAngular.js',
                                                  'vendor/textAngular/src/textAngularSetup.js',
                                                  'vendor/textAngular/src/textAngular.css'], serie: true},
      {name: 'angular-rickshaw',          files: ['vendor/d3/d3.min.js',
                                                  'vendor/rickshaw/rickshaw.js',
                                                  'vendor/rickshaw/rickshaw.min.css',
                                                  'vendor/angular-rickshaw/rickshaw.js'], serie: true},
      {name: 'angular-chartist',          files: ['vendor/chartist/dist/chartist.min.css',
                                                  'vendor/chartist/dist/chartist.js',
                                                  'vendor/angular-chartist.js/dist/angular-chartist.js'], serie: true},
      {name: 'ui.map',                    files: ['vendor/angular-ui-map/ui-map.js']},
      {name: 'datatables',                files: ['vendor/datatables/media/css/jquery.dataTables.css',
                                                  'vendor/datatables/media/js/jquery.dataTables.js',
                                                  'vendor/angular-datatables/dist/angular-datatables.js'], serie: true},
      {name: 'angular-jqcloud',           files: ['vendor/jqcloud2/dist/jqcloud.css',
                                                  'vendor/jqcloud2/dist/jqcloud.js',
                                                  'vendor/angular-jqcloud/angular-jqcloud.js']},
      {name: 'angularGrid',               files: ['vendor/ag-grid/dist/angular-grid.css',
                                                  'vendor/ag-grid/dist/angular-grid.js',
                                                  'vendor/ag-grid/dist/theme-dark.css',
                                                  'vendor/ag-grid/dist/theme-fresh.css']},
      {name: 'ng-nestable',               files: ['vendor/ng-nestable/src/angular-nestable.js',
                                                  'vendor/nestable/jquery.nestable.js']},
      {name: 'akoenig.deckgrid',          files: ['vendor/angular-deckgrid/angular-deckgrid.js']}
      
      
    ]
  })
;
/**=========================================================
 * Module: access-login.js
 * Demo for login api
 =========================================================*/
App.controller('LoginFormController', ['$scope', '$http', '$state', function($scope, $http, $state) {

  // bind here all data from the form
  $scope.account = {};
  // place the message if something goes wrong
  $scope.authMsg = '';

  $scope.login = function() {
    $scope.authMsg = '';

    if($scope.loginForm.$valid) {
        $http({
            method:"POST",
            url:"http://127.0.0.1:8001/loginjudge/",
            data:$scope.account
        })
        .success(
                function(response) {
                        if(response == 1){
                            alert("success");
                            $state.go('app.projectIcon');
                        }
                        else{
                            alert("please check your username and password");
                            $scope.authMsg = 'Incorrect credentials.';
                        }
                    }
                )
        .error(
               function() {
                        alert("fail");
                        $scope.authMsg = 'Server Request Error';
                          }
                );
    }
    else {
      // set as dirty if the user click directly to login so we show the validation messages
      $scope.loginForm.account_email.$dirty = true;
      $scope.loginForm.account_password.$dirty = true;
    }
  };

}]);
App.controller('UserBlockController', ['$scope', '$http', '$state',function($scope, $http,$state) {

  $scope.userBlockVisible = true;
  
  $scope.$on('toggleUserBlock', function(event, args) {

    $scope.userBlockVisible = ! $scope.userBlockVisible;
    
  });

  $scope.result = "result";

  $http({
            method:"POST",
            url:"http://127.0.0.1:8001/getaccount/",
        })

        .success(
                function(response) {
                    $scope.user = response;
                  }
                )

        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
  $scope.logresult = "result";
  $scope.logout = function() {

  $http({
            method:"POST",
            url:"http://127.0.0.1:8001/logout/",
        })

        .success(
                function() {
                    $scope.logresult = "success";
                    $state.go('page.login');
                    }
                )

        .error(
               function() {
                        $scope.logresult = "fail";
                          }
                );
  }

}]);

/**=========================================================
 * Module: access-register.js
 * Demo for register account api
 =========================================================*/

App.controller('RegisterFormController', ['$scope', '$http', '$state', function($scope, $http, $state) {

  // bind here all data from the form
  $scope.account = {};
  // place the message if something goes wrong
  $scope.authMsg = '';
    
  $scope.register = function() {
    $scope.authMsg = '';

    if($scope.registerForm.$valid) {
      $http({
            method:"POST",
            url:"http://127.0.0.1:8001/userregister/",
            data:$scope.account
        })

        .success(
                function() {
                    $scope.result = "success";
                    alert("注册成功，请登录");
                    $state.go('page.login');
                    }
                )

        .error(
               function() {
                        alert("账号已经存在，请登录");
                        $scope.result = "fail";
                          }
                );
    }
    else {
      // set as dirty if the user click directly to login so we show the validation messages
      $scope.registerForm.account_email.$dirty = true;
      $scope.registerForm.account_password.$dirty = true;
      $scope.registerForm.account_agreed.$dirty = true;
      
    }
  };

}]);
App.controller('PasswordFormController', ['$scope', '$http', '$state', function($scope, $http, $state) {

  // bind here all data from the form
  $scope.account = {};
  // place the message if something goes wrong
  $scope.authMsg = '';

  $scope.passwordupdate = function() {
    $scope.authMsg = '';

    $http({
            method:"POST",
            url:"http://127.0.0.1:8001/getaccount/",
        })

        .success(
                function(response) {

                    $scope.account.Email = response;

                    }
                )

        .error(
               function() {
                        $scope.result = "fail";
                          }
                );

    if($scope.passwordForm.$valid) {

        $http({
            method:"POST",
            url:"http://127.0.0.1:8001/passwordupdate/",
            data:$scope.account
        })
        .success(
                function(response){
                    if(response == 1){
                        alert("success");
                        $state.go('page.login');
                    }
                    else{
                      alert("fail");
                      $scope.result = "fail";
                    }
                  }
        )
        .error(
               function() {
                  alert("fail");
                  $scope.authMsg = 'Server Request Error';
                }
        );

    }
    else {
      // set as dirty if the user click directly to login so we show the validation messages
   
      $scope.passwordForm.account_password.$dirty = true;
      
    }
  };

}]);

App.controller('HomeCtrl',
        ["$sce", "$timeout", function ($sce, $timeout) {
            var controller = this;
            controller.state = null;
            controller.API = null;
            controller.currentVideo = 0;

            controller.onPlayerReady = function(API) {
                controller.API = API;
            };

            controller.onCompleteVideo = function() {
                controller.isCompleted = true;

                controller.currentVideo++;

                if (controller.currentVideo >= controller.videos.length) controller.currentVideo = 0;

                controller.setVideo(controller.currentVideo);
            };

            controller.videos = [
            {
                sources: [
                    {src: $sce.trustAsResourceUrl("http://7xi6l3.com1.z0.glb.clouddn.com/lyf.mp4"), type: "video/mp4"}
                ]
            }
        ];

            controller.config = {
                preload: "none",
                autoHide: false,
                autoHideTime: 3000,
                autoPlay: false,
                sources: controller.videos[0].sources,
                theme: {
                    url: "http://www.videogular.com/styles/themes/default/latest/videogular.css"
                },
                plugins: {
                    poster: "http://www.videogular.com/assets/images/videogular.png"
                }
            };

            controller.setVideo = function(index) {
                controller.API.stop();
                controller.currentVideo = index;
                controller.config.sources = controller.videos[index].sources;
                $timeout(controller.API.play.bind(controller.API), 100);
            };
        }]
    );

/**=========================================================
 * Module: article.js
 =========================================================*/

/**
 * AngularJS default filter with the following expression:
 * "person in people | filter: {name: $select.search, age: $select.search}"
 * performs a AND between 'name: $select.search' and 'age: $select.search'.
 * We want to perform a OR.
 */
App.filter('propsFilter', function() {
  return function(items, props) {
    var out = [];

    if (angular.isArray(items)) {
      items.forEach(function(item) {
        var itemMatches = false;

        var keys = Object.keys(props);
        for (var i = 0; i < keys.length; i++) {
          var prop = keys[i];
          var text = props[prop].toLowerCase();
          if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
            itemMatches = true;
            break;
          }
        }

        if (itemMatches) {
          out.push(item);
        }
      });
    } else {
      // Let the output be the input untouched
      out = items;
    }

    return out;
  };
});
App.filter('unique', function() {
   return function(collection, keyname) {
      var output = [], 
          keys = [];

      angular.forEach(collection, function(item) {
          var key = item[keyname];
          if(keys.indexOf(key) === -1) {
              keys.push(key);
              output.push(item);
          }
      });

      return output;
   };
});
App.controller('AngularCarouselController', ["$scope", function($scope) {

  $scope.colors = ["#fc0003", "#f70008", "#f2000d", "#ed0012", "#e80017", "#e3001c", "#de0021", "#d90026", "#d4002b", "#cf0030", "#c90036", "#c4003b", "#bf0040", "#ba0045", "#b5004a", "#b0004f", "#ab0054", "#a60059", "#a1005e", "#9c0063", "#960069", "#91006e", "#8c0073", "#870078", "#82007d", "#7d0082", "#780087", "#73008c", "#6e0091", "#690096", "#63009c", "#5e00a1", "#5900a6", "#5400ab", "#4f00b0", "#4a00b5", "#4500ba", "#4000bf", "#3b00c4", "#3600c9", "#3000cf", "#2b00d4", "#2600d9", "#2100de", "#1c00e3", "#1700e8", "#1200ed", "#0d00f2", "#0800f7", "#0300fc"];

  $scope.slides = [
    {id: 1, image: 'http://lorempixel.com/1200/500/people/2/'},
    {id: 2, image: 'http://lorempixel.com/1200/500/people/1/'},
    {id: 3, image: 'http://lorempixel.com/1200/500/people/2/'}
  ];

  function getSlide(target, style) {
      var i = target.length;
      return {
          id: (i + 1),
          label: 'slide #' + (i + 1),
          img: 'http://lorempixel.com/1200/500/' + style + '/' + ((i + 1) % 10) ,
          color: $scope.colors[ (i*10) % $scope.colors.length],
          odd: (i % 2 === 0)
      };
  }

  function addSlide(target, style) {
      target.push(getSlide(target, style));
  }

  $scope.carouselIndex = 3;
  $scope.carouselIndex2 = 0;
  $scope.carouselIndex2 = 1;
  $scope.carouselIndex3 = 5;
  $scope.carouselIndex4 = 5;

  function addSlides(target, style, qty) {
      for (var i=0; i < qty; i++) {
          addSlide(target, style);
      }
  }

  // 1st ngRepeat demo
  $scope.slides = [];
  addSlides($scope.slides, 'sports', 50);

  // 2nd ngRepeat demo
  $scope.slides2 = [];
  addSlides($scope.slides2, 'sports', 10);

  // 3rd ngRepeat demo
  $scope.slides3 = [];
  addSlides($scope.slides3, 'people', 50);

  // 4th ngRepeat demo
  $scope.slides4 = [];
  addSlides($scope.slides4, 'city', 50);


  // 5th ngRepeat demo
  $scope.slides6 = [];
  $scope.carouselIndex6 = 0;
  addSlides($scope.slides6, 'sports', 10);
  $scope.addSlide = function(at) {
      if(at==='head') {
          $scope.slides6.unshift(getSlide($scope.slides6, 'people'));
      } else {
          $scope.slides6.push(getSlide($scope.slides6, 'people'));
      }
  };

}]);

/**=========================================================
 * Module: code-editor.js
 * Codemirror code editor controller
 =========================================================*/

App.controller('CodeEditorController', ['$scope', '$http', '$ocLazyLoad', function ($scope, $http, $ocLazyLoad) {

  $scope.editorThemes = ['3024-day','3024-night','ambiance-mobile','ambiance','base16-dark','base16-light','blackboard','cobalt','eclipse','elegant','erlang-dark','lesser-dark','mbo','mdn-like','midnight','monokai','neat','neo','night','paraiso-dark','paraiso-light','pastel-on-dark','rubyblue','solarized','the-matrix','tomorrow-night-eighties','twilight','vibrant-ink','xq-dark','xq-light'];

  $scope.editorOpts = {
    mode: 'javascript',
    lineNumbers: true,
    matchBrackets: true,
    theme: '3024-day',
    viewportMargin: Infinity
  };

  $scope.refreshEditor = 0;

  // Load dinamically the stylesheet for the selected theme
  // You can use ozLazyLoad to load also the mode js based 
  // on the file extension that is loaded (see handle_filetree)
  $scope.loadTheme = function() {
    var BASE = 'vendor/codemirror/theme/';
    $ocLazyLoad.load(BASE + $scope.editorOpts.theme + '.css');
    $scope.refreshEditor = !$scope.refreshEditor;
  };
  // load default theme
  $scope.loadTheme($scope.editorOpts.theme);
  // Add some initial text
  $scope.code = "";


  // Tree

  var selectedBranch;
  $scope.handle_filetree = function(branch) {
    
    selectedBranch = branch;

    var basePath = 'server/editor/'; 
    var isFolder = !!branch.children.length;

    $scope.output = branch.path;

    if (branch.data && branch.data.description) {
      $scope.output += '(' + branch.data.description + ')';
      return $scope.output;
    }

    console.log("You selected: " + branch.label + ' - isFolder? ' + isFolder);

    if ( ! isFolder ) {
      $scope.editorOpts.mode = detectMode(branch.path);
          if($scope.editorOpts.mode == "jpg" || $scope.editorOpts.mode == "png"){
            $scope.file = true;
            $scope.picture = true;
          } else{
            $scope.picture = false;
            $scope.file = false;
          }

      $http
        .get( basePath + branch.path )
        .success(function(response){
          
          console.log('Loaded.. ' + branch.path);
          // set the new code into the editor
          $scope.code = response;
          
          $scope.editorOpts.mode = detectMode(branch.path);
          console.log( 'Mode is: ' + $scope.editorOpts.mode);

        });
    }

  };

  function detectMode(file) {
    var ext = file.split('.');
    ext = ext ? ext[ext.length - 1] : '';
    switch (ext) {
      case 'html':  return 'htmlmixed';
      case 'css':   return 'css';
      case 'jpg':   return 'jpg';
      case 'png':   return 'png';
      default:      return 'javascript';
    }
  }
  
  var tree;
  tree = $scope.filetree = {};
  
}]).service('LoadTreeService', ["$resource", function($resource) {
   return $resource('server/editor/filetree.json');
}]);

/**=========================================================
 * Module: datatable,js
 * Angular Datatable controller
 =========================================================*/

/**=========================================================
 * Module: demo-carousel.js
 * Provides a simple demo for bootstrap ui carousel
 =========================================================*/

App.controller('CarouselDemoCtrl', ['$scope', function ($scope) {
  $scope.myInterval = 5000;

  $scope.slides = [
    {id: 1, image: 'http://7xi6l3.com1.z0.glb.clouddn.com/slider1.jpg'},
    {id: 2, image: 'http://7xi6l3.com1.z0.glb.clouddn.com/slider2.jpg'},
    {id: 3, image: 'http://7xi6l3.com1.z0.glb.clouddn.com/slider3.jpg'}
  ];
  
}]);

App.controller('ListDemoCtrl', ['$scope', function ($scope) {
  
  $scope.lists = [
    {id: 1, text: '人类基因数据组Ａ'},
    {id: 2, text: '人类基因数据组Ｂ'},
    {id: 3, text: '人类基因数据组Ａ'}
  ];
  
}]);

App.controller('FormDemoCtrl', ["$scope", "$resource", function($scope, $resource) {
  'use strict';

  // the following allow to request array $resource instead of object (default)
  var actions = {'get': {method: 'GET', isArray: true}};
  
  // Tags inputs
  // ----------------------------------- 
  var Cities = $resource('server/cities.json', {}, actions);

  Cities.get(function(data){

      $scope.cities = data;

  });
  // for non ajax form just fill the scope variable
  // $scope.cities = ['Amsterdam','Washington','Sydney','Beijing','Cairo'];

  // Slider demo values
  $scope.slider1 = 5;
  $scope.slider2 = 10;
  $scope.slider3 = 15;
  $scope.slider4 = 20;
  $scope.slider5 = 25;
  $scope.slider6 = 30;
  $scope.slider7 = 10;
  $scope.slider8 = [250,750];

  // Chosen data
  // ----------------------------------- 

  var States = $resource('server/chosen-states.json', {},  {'query':    {method:'GET', isArray:true} });

  $scope.states = States.query();


  $scope.alertSubmit = function(){
    return false;
  };

  // Angular wysiwyg 
  // ----------------------------------- 

  $scope.wysiwygContent = '<p> Write something here.. </p>';

  // Text Angular (wysiwyg)
  // ----------------------------------- 
  
  $scope.htmlContent = '<h2>Try me!</h2><p>textAngular is a super cool WYSIWYG Text Editor directive for AngularJS</p><p><b>Features:</b></p><ol><li>Automatic Seamless Two-Way-Binding</li><li style="color: blue;">Super Easy <b>Theming</b> Options</li><li>Simple Editor Instance Creation</li><li>Safely Parses Html for Custom Toolbar Icons</li><li>Doesn&apos;t Use an iFrame</li><li>Works with Firefox, Chrome, and IE8+</li></ol><p><a href="https://github.com/fraywing/textAngular">Source</a> </p>';


}]);

/**=========================================================
 * Module: demo-panels.js
 * Provides a simple demo for panel actions
 =========================================================*/

App.controller('PanelsCtrl', ['$scope', '$timeout', function ($scope, $timeout) {

  // PANEL COLLAPSE EVENTS
  // ----------------------------------- 

  // We can use panel id name for the boolean flag to [un]collapse the panel
  $scope.$watch('panelDemo1',function(newVal){
      
      console.log('panelDemo1 collapsed: ' + newVal);

  });


  // PANEL DISMISS EVENTS
  // ----------------------------------- 

  // Before remove panel
  $scope.$on('panel-remove', function(event, id, deferred){
    
    console.log('Panel #' + id + ' removing');
    
    // Here is obligatory to call the resolve() if we pretend to remove the panel finally
    // Not calling resolve() will NOT remove the panel
    // It's up to your app to decide if panel should be removed or not
    deferred.resolve();
  
  });

  // Panel removed ( only if above was resolved() )
  $scope.$on('panel-removed', function(event, id){

    console.log('Panel #' + id + ' removed');

  });


  // PANEL REFRESH EVENTS
  // ----------------------------------- 

  $scope.$on('panel-refresh', function(event, id) {
    var secs = 3;
    
    console.log('Refreshing during ' + secs +'s #'+id);

    $timeout(function(){
      // directive listen for to remove the spinner 
      // after we end up to perform own operations
      $scope.$broadcast('removeSpinner', id);
      
      console.log('Refreshed #' + id);

    }, 3000);

  });

  // PANELS VIA NG-REPEAT
  // ----------------------------------- 

  $scope.panels = [
    {
      id: 'panelRepeat1',
      title: 'Panel Title 1',
      body: 'Nulla eget lorem leo, sit amet elementum lorem. '
    },
    {
      id: 'panelRepeat2',
      title: 'Panel Title 2',
      body: 'Nulla eget lorem leo, sit amet elementum lorem. '
    },
    {
      id: 'panelRepeat3',
      title: 'Panel Title 3',
      body: 'Nulla eget lorem leo, sit amet elementum lorem. '
    }
  ];

}]);
/**=========================================================
 * Module: demo-popover.js
 * Provides a simple demo for popovers
 =========================================================*/

App.controller('PopoverDemoCtrl', ['$scope', function ($scope) {
  
  $scope.dynamicPopover = 'Hello, World!';
  $scope.dynamicPopoverTitle = 'Title';

}]);
/**=========================================================
 * Module: demo-progress.js
 * Provides a simple demo to animate progress bar
 =========================================================*/

App.controller('RatingDemoCtrl', ['$scope', function ($scope) {

  $scope.rate = 0;
  $scope.max = 1;
  $scope.isReadonly = false;

  $scope.hoveringOver = function(value) {
    $scope.overStar = value;
    $scope.percent = 100 * (value / $scope.max);
  };

  $scope.ratingStates = [
    {stateOn: 'fa fa-check', stateOff: 'fa fa-check-circle'},
    {stateOn: 'fa fa-star', stateOff: 'fa fa-star-o'},
    {stateOn: 'fa fa-heart', stateOff: 'fa fa-ban'},
    {stateOn: 'fa fa-heart'},
    {stateOff: 'fa fa-power-off'}
  ];

}]);
/**=========================================================
 * Module: demo-timepicker.js
 * Provides a simple demo for bootstrap ui timepicker
 =========================================================*/

App.controller('ToasterDemoCtrl', ['$scope', 'toaster', function($scope, toaster) {

  $scope.toaster = {
      type:  'success',
      title: 'Title',
      text:  'Message'
  };

  $scope.pop = function() {
    toaster.pop($scope.toaster.type, $scope.toaster.title, $scope.toaster.text);
  };

}]);
/**=========================================================
 * Module: demo-tooltip.js
 * Provides a simple demo for tooltip
 =========================================================*/
App.controller('TooltipDemoCtrl', ['$scope', function ($scope) {

  $scope.dynamicTooltip = 'Hello, World!';
  $scope.dynamicTooltipText = 'dynamic';
  $scope.htmlTooltip = 'I\'ve been made <b>bold</b>!';

}]);

/**=========================================================
 * Module: form-imgcrop.js
 * Image crop controller
 =========================================================*/
App.controller('ImageCropController', ["$scope", function($scope) {

  $scope.reset = function() {
    $scope.myImage        = '';
    $scope.myCroppedImage = '';
    $scope.imgcropType    = "square";
  };

  $scope.reset();
  $scope.uploadimage = function() {
    alert("success");
  };

  var handleFileSelect=function(evt) {
    var file=evt.currentTarget.files[0];
    var reader = new FileReader();
    reader.onload = function (evt) {
      $scope.$apply(function($scope){
        $scope.myImage=evt.target.result;
      });
    };
    if(file)
      reader.readAsDataURL(file);
  };
  angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect);
}]);
/**=========================================================
 * Module: main.js
 * Main Application Controller
 =========================================================*/

App.controller('AppController',
  ['$rootScope', '$scope', '$state', '$translate', '$window', '$localStorage', '$timeout', 'toggleStateService', 'colors', 'browser', 'cfpLoadingBar',
  function($rootScope, $scope, $state, $translate, $window, $localStorage, $timeout, toggle, colors, browser, cfpLoadingBar) {
    "use strict";

    // Setup the layout mode
    $rootScope.app.layout.horizontal = ( $rootScope.$stateParams.layout == 'app-h') ;

    // Loading bar transition
    // ----------------------------------- 
    var thBar;
    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
        if($('.wrapper > section').length) // check if bar container exists
          thBar = $timeout(function() {
            cfpLoadingBar.start();
          }, 0); // sets a latency Threshold
    });
    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
        event.targetScope.$watch("$viewContentLoaded", function () {
          $timeout.cancel(thBar);
          cfpLoadingBar.complete();
        });
    });


    // Hook not found
    $rootScope.$on('$stateNotFound',
      function(event, unfoundState, fromState, fromParams) {
          console.log(unfoundState.to); // "lazy.state"
          console.log(unfoundState.toParams); // {a:1, b:2}
          console.log(unfoundState.options); // {inherit:false} + default options
      });
    // Hook error
    $rootScope.$on('$stateChangeError',
      function(event, toState, toParams, fromState, fromParams, error){
        console.log(error);
      });
    // Hook success
    $rootScope.$on('$stateChangeSuccess',
      function(event, toState, toParams, fromState, fromParams) {
        // display new view from top
        $window.scrollTo(0, 0);
        // Save the route title
        $rootScope.currTitle = $state.current.title;
      });

    $rootScope.currTitle = $state.current.title;
    $rootScope.pageTitle = function() {
      var title = $rootScope.app.name + ' - ' + ($rootScope.currTitle || $rootScope.app.description);
      document.title = title;
      return title;
    };

    // iPad may presents ghost click issues
    // if( ! browser.ipad )
      // FastClick.attach(document.body);

    // Close submenu when sidebar change from collapsed to normal
    $rootScope.$watch('app.layout.isCollapsed', function(newValue, oldValue) {
      if( newValue === false )
        $rootScope.$broadcast('closeSidebarMenu');
    });

    // Restore layout settings
    if( angular.isDefined($localStorage.layout) )
      $scope.app.layout = $localStorage.layout;
    else
      $localStorage.layout = $scope.app.layout;

    $rootScope.$watch("app.layout", function () {
      $localStorage.layout = $scope.app.layout;
    }, true);

    
    // Allows to use branding color with interpolation
    // {{ colorByName('primary') }}
    $scope.colorByName = colors.byName;

    // Hides/show user avatar on sidebar
    $scope.toggleUserBlock = function(){
      $scope.$broadcast('toggleUserBlock');
    };

    // Internationalization
    // ----------------------

    $scope.language = {
      // Handles language dropdown
      listIsOpen: false,
      // list of available languages
      available: {
        'en':       'English',
        'es_AR':    'Español'
      },
      // display always the current ui language
      init: function () {
        var proposedLanguage = $translate.proposedLanguage() || $translate.use();
        var preferredLanguage = $translate.preferredLanguage(); // we know we have set a preferred one in app.config
        $scope.language.selected = $scope.language.available[ (proposedLanguage || preferredLanguage) ];
      },
      set: function (localeId, ev) {
        // Set the new idiom
        $translate.use(localeId);
        // save a reference for the current language
        $scope.language.selected = $scope.language.available[localeId];
        // finally toggle dropdown
        $scope.language.listIsOpen = ! $scope.language.listIsOpen;
      }
    };

    $scope.language.init();

    // Restore application classes state
    toggle.restoreState( $(document.body) );

    // cancel click event easily
    $rootScope.cancel = function($event) {
      $event.stopPropagation();
    };

}]);

/**=========================================================
 * Module: masonry-deck.js
 * Demo for Angular Deck
 =========================================================*/
App.controller('MasonryDeckController', ['$scope', '$filter', '$http', 'editableOptions', 'editableThemes','$q','$resource', 'DTOptionsBuilder', 'DTColumnDefBuilder',
  function($scope,$filter, $http, editableOptions, editableThemes, $q,$resource, DTOptionsBuilder, DTColumnDefBuilder) {
  'use strict';

  // Ajax
  
  $scope.dtOptions = DTOptionsBuilder.newOptions().withPaginationType('full_numbers');
  $scope.dtColumnDefs = [
      DTColumnDefBuilder.newColumnDef(0).notSortable(),
      DTColumnDefBuilder.newColumnDef(1),
      DTColumnDefBuilder.newColumnDef(2),
      DTColumnDefBuilder.newColumnDef(3),
      DTColumnDefBuilder.newColumnDef(4).notSortable()
  ];

  // Ajax

  $resource('server/listphotos.json').query().$promise.then(function(cards) {
      $scope.cards = cards;
  });

  $scope.selected = [];
     $scope.selectedTags = [];
 
     var updateSelected = function(action,id,name){
         if(action == 'add' && $scope.selected.indexOf(id) == -1){
             $scope.selected.push(id);
             $scope.selectedTags.push(name);
         }
         if(action == 'remove' && $scope.selected.indexOf(id)!=-1){
            var idx = $scope.selected.indexOf(id);
             $scope.selected.splice(idx,1);
             $scope.selectedTags.splice(idx,1);
         }
     }
 
     $scope.updateSelection = function($event, id){
         var checkbox = $event.target;
         var action = (checkbox.checked?'add':'remove');
         updateSelected(action,id,checkbox.name);
         $scope.datahead = !$scope.datahead;
     }
 
     $scope.isSelected = function(id){
         return $scope.selected.indexOf(id)>=0;
     }
  
}]).directive('imageloaded', [
    // Copyright(c) 2013 André König <akoenig@posteo.de>
    // MIT Licensed
    function () {

        'use strict';

        return {
            restrict: 'A',

            link: function(scope, element, attrs) {   
                var cssClass = attrs.loadedclass;

                element.bind('load', function (e) {
                    angular.element(element).addClass(cssClass);
                });
            }
        }
    }
]);
App.controller('TopDemoCtrl', ['$scope', '$resource',
  function($scope, $resource) {
  'use strict';

  // Ajax

  $resource('server/listtops.json').query().$promise.then(function(tops) {
      $scope.tops = tops;
  });
}]);
/**=========================================================
 * Module: modals.js
 * Provides a simple way to implement bootstrap modals from templates
 =========================================================*/

App.controller('SeniorController', ['$scope', '$modal', function ($scope, $modal) {

  $scope.openSenior = function (size) {

    var modalInstance = $modal.open({
      templateUrl: '/myModalSenior.html',
      controller: ModalInstanceCtrl,
      size: size,
      backdrop: 'static',
      keyboard: false
    });
  };

$(function(){
      $('.modal-content').each(function(){
        $(this).dragging({
          move : 'both',
          randomPosition : true ,
          hander:'.hander'
        });
      });
    });
  // Please note that $modalInstance represents a modal window (instance) dependency.
  // It is not the same as the $modal service used above.

  var ModalInstanceCtrl = function ($scope, $modalInstance) {


    $scope.cancel = function () {
      $modalInstance.dismiss('cancel');
    };
  };
  ModalInstanceCtrl.$inject = ["$scope", "$modalInstance"];

}]);
App.controller('AddProjectFileController', ["$scope", "$rootScope", "ngDialog", function ($scope, $rootScope, ngDialog) {
  'user strict';
  $scope.openConfirm = function () {
    ngDialog.openConfirm({
      template: 'modalDialogId',
      className: 'ngdialog-theme-default'
    }).then(function (value) {
      console.log('Modal promise resolved. Value: ', value);
    }, function (reason) {
      console.log('Modal promise rejected. Reason: ', reason);
    });
  };

}]);
App.controller('AddProjectController', ['$scope', "$rootScope", 'ngDialog', function ($scope, $rootScope,ngDialog) {

  $scope.openWithoutOverlay = function () {
    ngDialog.openConfirm({
      template: 'addProjectId',
      className: 'ngdialog-theme-default'
    }).then(function (value) {
      console.log('Modal promise resolved. Value: ', value);
    }, function (reason) {
      console.log('Modal promise rejected. Reason: ', reason);
    });
  };

}]);
App.controller('TabController', ['$scope',  function ($scope) {

  $scope.tabs = [
      { "id":1,"ch":"研究","eh": "studys" },
      { "id":2,"ch":"实验","eh": "experiments" },
      { "id":3,"ch":"样本","eh": "samples" },
      { "id":4,"ch":"运行","eh": "runs" }
  ];
}]);
App.controller('TypeController', ['$scope',  function ($scope) {

  $scope.types = [
      { "id":1,"ch":"研究","eh": "studys" },
      { "id":2,"ch":"实验","eh": "experiments" },
      { "id":3,"ch":"样本","eh": "samples" },
      { "id":4,"ch":"运行","eh": "runs" }
  ];
}]);
App.controller('SideController', ['$scope','$http',  function ($scope,$http) {

  $scope.sides = [
      { name: "生物" }
  ];
  $scope.projects = [
      { name: "原核生物" },
      { name: "原生生物" },
      { name: "真菌" },
      { name: "动物" },
      { name: "植物" }
  ];
  $scope.types = [
      { name:"界(kingdom)"},
      { name:"门（phylum）"},
      { name:"纲(class)"},
      { name:"目(order)"},
      { name: "科(family)"},
      { name:"属(genus)"},
      { name:"种(species)"}
    ];
  $(function(){ 
    // 导航左侧栏js效果 start
    $(".pullDownList li").hover(function(){
      $(".yMenuListCon").fadeIn();
      var index=$(this).index(".pullDownList li");
      if (!($(this).hasClass("menulihover")||$(this).hasClass("menuliselected"))) {
        $($(".yBannerList")[index]).css("display","block").siblings().css("display","none");
        $($(".yBannerList")[index]).removeClass("ybannerExposure");
        setTimeout(function(){
        $($(".yBannerList")[index]).addClass("ybannerExposure");
        },60)
      }else{  
      }
      $(this).addClass("menulihover").siblings().removeClass("menulihover");
        $(this).addClass("menuliselected").siblings().removeClass("menuliselected");
      $($(".yMenuListConin")[index]).fadeIn().siblings().fadeOut();
    },function(){
      
    })
    $(".pullDown").mouseleave(function(){
      $(".yMenuListCon").fadeOut();
      $(".yMenuListConin").fadeOut();
      $(".pullDownList li").removeClass("menulihover");

    })
    // 导航左侧栏js效果  end
    
  })

}]);
App.controller('DetailController', ['$scope','$http',"$stateParams",  function ($scope,$http,$stateParams) {
$scope.inputdata={};
$scope.inputdata.keyword=$stateParams.projectName;
console.log($scope.inputdata.keyword);
if($stateParams.typeName == "studys"){
$http({
            method:"POST",
            url:"http://127.0.0.1:8001/studysearch/",
            data:$scope.inputdata
        })


        .success(
                function(response) {
                    return $scope.result = response;
                    }
                )


        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
      }else if($stateParams.typeName == "experiments"){
$http({
            method:"POST",
            url:"http://127.0.0.1:8001/experimentsearch/",
            data:$scope.inputdata
        })


        .success(
                function(response) {
                    return $scope.result = response;
                    }
                )


        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
      }else if($stateParams.typeName == "samples"){
$http({
            method:"POST",
            url:"http://127.0.0.1:8001/samplesearch/",
            data:$scope.inputdata
        })


        .success(
                function(response) {
                    return $scope.result = response;
                    }
                )


        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
        }else if($stateParams.typeName == "runs"){
$http({
            method:"POST",
            url:"http://127.0.0.1:8001/runssearch/",
            data:$scope.inputdata
        })


        .success(
                function(response) {
                    return $scope.result = response;
                    }
                )


        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
      }
  $scope.details = [
      { 
       "id": 1,
        "title":"进化基因组学和群体遗传学致病性链球菌",
        "src": "http://7xi6l3.com1.z0.glb.clouddn.com/slider1.jpg",
        "love": "24",
        "comment":"1",
        "abstract":"这个项目的目的是收集比较基因组序列数据在重要的人类病原体无乳链球菌为分析选择压力和人口史的目的多株，采用种群的遗传基础的方法。",
        "references":"",
        "organisms":"无乳链球菌bsu174",
        "type":"全基因组测序",
        "description":"这个项目的目的是收集比较基因组序列数据在重要的人类病原体无乳链球菌为分析选择压力和人口史的目的多株，采用种群的遗传基础的方法。",
        "submitter":"J. Craig Venter Institute",
        "Study":"http://localhost/angular-project/#/app-h/detail",
        "Experiment":"http://localhost/angular-project/#/app-h/detail",
        "Example":"http://localhost/angular-project/#/app-h/detail",
        "Run":"http://localhost/angular-project/#/app-h/detail",
      }
  ];
}]);
App.controller('CommentController', ['$scope',  function ($scope) {

  $scope.comments = [
      { 
       "id": 1,
        "src": "http://7xi6l3.com1.z0.glb.clouddn.com/slider1.jpg",
        "name":"john",
        "com":"项目很好"
      },
      { 
       "id": 2,
        "src": "http://7xi6l3.com1.z0.glb.clouddn.com/slider1.jpg",
        "name":"bob",
        "com":"项目很好"
      },
      { 
       "id": 3,
        "src": "http://7xi6l3.com1.z0.glb.clouddn.com/slider1.jpg",
        "name":"an",
        "com":"项目很好"
      },
      { 
       "id": 4,
        "src": "http://7xi6l3.com1.z0.glb.clouddn.com/slider1.jpg",
        "name":"ei",
        "com":"项目很好"
      }
  ];
}]);
App.controller('FileController', ['$scope',  function ($scope) {

  $scope.files = [
      { 
       "id": 1,
        "src": "http://7xi6l3.com1.z0.glb.clouddn.com/zip.png",
        "name":"进化学",
        "com":"这个项目的目的是收集比较基因组序列数据在重要的人类病原体无乳链球菌为分析选择压力和人口史的目的多株，采用种群的遗传基础的方法。"
      },
      { 
       "id": 2,
        "src": "http://7xi6l3.com1.z0.glb.clouddn.com/zip.png",
        "name":"群体遗传学",
        "com":"这个项目的目的是收集比较基因组序列数据在重要的人类病原体无乳链球菌为分析选择压力和人口史的目的多株，采用种群的遗传基础的方法。"
      },
      { 
       "id": 3,
        "src": "http://7xi6l3.com1.z0.glb.clouddn.com/psd.png",
        "name":"致病性链球菌",
        "com":"这个项目的目的是收集比较基因组序列数据在重要的人类病原体无乳链球菌为分析选择压力和人口史的目的多株，采用种群的遗传基础的方法。"
      },
      { 
       "id": 4,
        "src": "http://7xi6l3.com1.z0.glb.clouddn.com/rar.gif",
        "name":"基因组学",
        "com":"这个项目的目的是收集比较基因组序列数据在重要的人类病原体无乳链球菌为分析选择压力和人口史的目的多株，采用种群的遗传基础的方法。"
      }
  ];
}]);

App.controller('FullPageController', ['$scope',  function ($scope) {

  $('#dowebok').fullpage({
      navigation: true
    });
}]);

App.controller('TotalController', ['$scope',  function ($scope) {

  $scope.totals = [
      { "name":"项目数量","summary":"1","cor": "text-purple","pattern":"fa-cloud-upload" },
      { "name":"文件存储", "summary":"5","cor": "text-info","pattern":"fa-file-text-o"  },
      { "name":"下载流量","summary":"2","cor": "text-danger","pattern":"fa-exclamation" },
      { "name":"分享","summary":"1","cor": "text-success","pattern":"fa-clock-o" }
  ];
  $scope.colors = [
      { "cor": "text-purple","pattern":"fa-cloud-upload" },
      { "cor": "text-info","pattern":"fa-file-text-o" },
      { "cor": "text-danger","pattern":"fa-exclamation"},
      { "cor": "text-success","pattern":"fa-clock-o" }
  ];
}]);
App.controller('SelectController', ['$scope', '$resource',
  function($scope, $resource) {
  'use strict';

  // Ajax

  //$resource('server/selectdata.json').query().$promise.then(function(selects) {
      //$scope.selects = selects;
 // });
 $scope.users = [
                    {
                        id: 0,
                        name: 's1',
                        interest: [
                            'ex1',
                            'ex2'
                        ]
                    },
                    {
                        id: 1,
                        name: 's2',
                        interest: [
                            'ex3',
                            'ex4'
                        ]
                    }
                ];
}]);
App.controller('ShareController', ['$scope', '$modal', function ($scope, $modal) {

  $scope.openshare = function (size) {

    var modalInstance = $modal.open({
      templateUrl: '/myModalShare.html',
      controller: ModalInstanceCtrl,
      size: size
    });
  };

  // Please note that $modalInstance represents a modal window (instance) dependency.
  // It is not the same as the $modal service used above.

  var ModalInstanceCtrl = function ($scope, $modalInstance) {

    $scope.ok = function () {
      $modalInstance.close('closed');
    };

    $scope.cancel = function () {
      $modalInstance.dismiss('cancel');
    };
  };
  ModalInstanceCtrl.$inject = ["$scope", "$modalInstance"];

}]);

App.controller('ShareLinkDemoCtrl', ['$scope', 'toaster', function($scope, toaster) {

  $scope.toaster = {
      type:  'success',
      text:  '成功分享'
  };

  $scope.pop = function() {
    toaster.pop($scope.toaster.type, $scope.toaster.text);
  };

}]);
App.controller('ShareOtherController', ['$scope', 'toaster', function($scope, toaster) {
  window._bd_share_config={
    "common":{
      "bdSnsKey":{},
      "bdText":"基于Web的基因组数据库管理系统",
      "bdMini":"2",
      "bdPic":"http://7xi6l3.com1.z0.glb.clouddn.com/slider1.jpg",
      "bdStyle":"0",
      "bdSize":"64"
    },
    "share":{},
    "image":{
      "viewList":["qzone","tsina","tqq","renren","weixin"],
      "viewText":"分享到：",
      "viewSize":"64"
    },
    "selectShare":{
      "bdContainerClass":null,
      "bdSelectMiniList":["qzone","tsina","tqq","renren","weixin"]
    }
  };
  with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
}]);
App.controller('ShareEmailController', ['$scope', '$http', '$state', function($scope, $http, $state) {

  // bind here all data from the form
  $scope.account = {};
  // place the message if something goes wrong
  $scope.authMsg = '';
    
  $scope.shareEmail = function() {
    $scope.authMsg = '';

    if($scope.shareEmailForm.$valid) {

      $http
        .post('api/account/shareEmail', {email: $scope.account.email})
        .then(function(response) {
          // assumes if ok, response is an object with some data, if not, a string with error
          // customize according to your api
          if ( !response.account ) {
            $scope.authMsg = response;
          }else{
            $state.go('app-h.home');
          }
        }, function(x) {
          $scope.authMsg = 'Server Request Error';
        });
    }
    else {
      // set as dirty if the user click directly to login so we show the validation messages
      $scope.shareEmailForm.account_email.$dirty = true;
    
    }
  };

}]);
App.controller('PerProjectController', ['$scope', '$filter', '$http', 'editableOptions', 'editableThemes','$q','$resource', 'DTOptionsBuilder', 'DTColumnDefBuilder',"$stateParams",
  function($scope, $filter, $http, editableOptions, editableThemes, $q,$resource, DTOptionsBuilder, DTColumnDefBuilder,$stateParams) {
  'use strict';

  // Ajax
  
  $scope.dtOptions = DTOptionsBuilder.newOptions().withPaginationType('full_numbers');
  $scope.dtColumnDefs = [
      DTColumnDefBuilder.newColumnDef(0).notSortable(),
      DTColumnDefBuilder.newColumnDef(1),
      DTColumnDefBuilder.newColumnDef(2),
      DTColumnDefBuilder.newColumnDef(3).notSortable()
  ];

  if($stateParams.perTypeName=="studys"){
    $http({
            method:"GET",
            url:"http://127.0.0.1:8001/studylist/"
        })

        .success(
                function(response) {
                    $scope.projects = response;
                    }
                )
        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
      }
      else if($stateParams.perTypeName=="experiments"){
      $http({
                method:"GET",
                url:"http://127.0.0.1:8001/experimentlist/"
            })

            .success(
                    function(response) {
                        $scope.projects = response;
                        }
                    )
            .error(
                   function() {
                            $scope.result = "fail";
                              }
                    );
      }
      else if($stateParams.perTypeName=="samples"){
      $http({
              method:"GET",
              url:"http://127.0.0.1:8001/samplelist/"
          })

          .success(
                  function(response) {
                      $scope.projects = response;
                      }
                  )
          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  );
      }else if($stateParams.perTypeName=="runs"){
      $http({
              method:"GET",
              url:"http://127.0.0.1:8001/runslist/"
          })

          .success(
                  function(response) {
                      $scope.projects = response;
                      }
                  )
          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  ); 
      }
  
  $scope.savePerproject = function(data, id) {
    //$scope.user not updated yet
    angular.extend(data, {id: id});
    console.log('Saving Perproject: ' + id);
    // return $http.post('/saveUser', data);
  };

  // remove user
  $scope.removePerproject = function(index) {

 $scope.study={};
 if($stateParams.perTypeName=="studys"){
 //  $scope.studys.splice(index, 1);
  $scope.study.Title = index;
  console.log(index);
    $http({
            method:"POST",
            url:"http://127.0.0.1:8001/studydelete/",
            data:$scope.study
        })

        .success(
                function() {
                    alert("成功删除");
                    return $scope.result = "success";
                    }
                )


        .error(
               function() {
                        alert("删除失败");
                        $scope.result = "fail";
                          }
                );

    }else if($stateParams.perTypeName=="experiments"){
 //  $scope.studys.splice(index, 1);
  $scope.experiment.Title = index;
  console.log(index);
    $http({
            method:"POST",
            url:"http://127.0.0.1:8001/experimentdelete/",
            data:$scope.experiment
        })

        .success(
                function() {
                    alert("成功删除");
                    return $scope.result = "success";
                    }
                )


        .error(
               function() {
                        alert("删除失败");
                        $scope.result = "fail";
                          }
                );

    }else if($stateParams.perTypeName=="samples"){
 //  $scope.studys.splice(index, 1);
  $scope.sample.Title = index;
  console.log(index);
    $http({
            method:"POST",
            url:"http://127.0.0.1:8001/sampletdelete/",
            data:$scope.sample
        })

        .success(
                function() {
                    alert("成功删除");
                    return $scope.result = "success";
                    }
                )


        .error(
               function() {
                        alert("删除失败");
                        $scope.result = "fail";
                          }
                );

    }else if($stateParams.perTypeName=="runs"){
 //  $scope.studys.splice(index, 1);
  $scope.run.Title = index;
  console.log(index);
    $http({
            method:"POST",
            url:"http://127.0.0.1:8001/rundelete/",
            data:$scope.run
        })

        .success(
                function() {
                    alert("成功删除");
                    return $scope.result = "success";
                    }
                )


        .error(
               function() {
                        alert("删除失败");
                        $scope.result = "fail";
                          }
                );

    }
  };

  // editable column
  // ----------------------------------- 

  // editable table
  // ----------------------------------- 

  // filter users to show
  $scope.filterPerproject = function(user) {
    return perproject.isDeleted !== true;
  };

  // mark user as deleted
  $scope.deletePerproject = function(id) {
    var filtered = $filter('filter')($scope.perprojects, {id: id});
    if (filtered.length) {
      filtered[0].isDeleted = true;
    }
  };

  // cancel all changes
  $scope.cancel = function() {
    for (var i = $scope.perprojects.length; i--;) {
      var perproject = $scope.perprojects[i];
      // undelete
      if (perproject.isDeleted) {
        delete perproject.isDeleted;
      }
      // remove new 
      if (perproject.isNew) {
        $scope.perprojects.splice(i, 1);
      }
    }
  };
  
  $scope.selected = [];
  $scope.selectedTags = [];

  $scope.allCheckOrNot=function($event){
    var checkbox = $event.target;
    if(checkbox.checked){
      allCkb();
    }else{
      unAllCkb()
    }
  }
  function allCkb() {
    $('tbody input[type=checkbox]').each(function (index,item) {
      var checkbox=item;
      var id = $(checkbox).data('_id');
      updateSelected('add', id, checkbox.name);
      this.checked = true;
    });
  }

  function unAllCkb(){
    $('tbody input[type=checkbox]').each(function (index,item) {
      var checkbox=item;
      var id = $(checkbox).data('_id');
      updateSelected('remove', id, checkbox.name);
      this.checked = false;
    });
  }
  var updateSelected = function (action, id, name) {
    if (action == 'add' && $scope.selected.indexOf(id) == -1) {
    $scope.selected.push(id);
    $scope.selectedTags.push(name);
  }
  if (action == 'remove' && $scope.selected.indexOf(id) != -1) {
    var idx = $scope.selected.indexOf(id);
    $scope.selected.splice(idx, 1);
    $scope.selectedTags.splice(idx,1);
    var CheckBox=document.getElementById("all");
     CheckBox.checked=false;
  }
  if ($scope.selected.length > 0) {
    $scope.prolist=true;
  } else {
    $scope.prolist=false;
  }
//alert($scope.selected);

}

  $scope.updateSelection = function ($event) {
    var checkbox = $event.target;
    var id = $(checkbox).data('_id');
    var action = (checkbox.checked ? 'add' : 'remove');
    updateSelected(action, id, checkbox.name);
  }
  $scope.isSelected = function(id){
         return $scope.selected.indexOf(id)>=0;
  }
}]);
App.controller('ProFileController', ['$scope', '$filter', '$http', 'editableOptions', 'editableThemes','$q','$resource', 'DTOptionsBuilder', 'DTColumnDefBuilder',
  function($scope, $filter, $http, editableOptions, editableThemes, $q,$resource, DTOptionsBuilder, DTColumnDefBuilder) {
  'use strict';
 
  // Ajax
  $scope.dtOptions = DTOptionsBuilder.newOptions().withPaginationType('full_numbers');
  $scope.dtColumnDefs = [
      DTColumnDefBuilder.newColumnDef(0).notSortable(),
      DTColumnDefBuilder.newColumnDef(1),
      DTColumnDefBuilder.newColumnDef(2),
      DTColumnDefBuilder.newColumnDef(3),
      DTColumnDefBuilder.newColumnDef(4).notSortable()
  ];
  // editable row
  // ----------------------------------- 
  $scope.proFiles = [
                    {
                        id: 0,name: 'index.doc',size: '2M',type:'doc', editTime:'2015/5/8',path: 'data/index.doc'
                    },
                    {
                        id: 1,name: 'bg2.png',size: '2M',type:'png', editTime:'2015/5/8',path: 'data/bg2.png'
                    }
                ];
  
  $scope.selected = [];
  $scope.selectedTags = [];

  $scope.allCheckOrNot=function($event){
    var checkbox = $event.target;
    if(checkbox.checked){
      allCkb();
    }else{
      unAllCkb()
    }
  }
  function allCkb() {
    $('tbody input[type=checkbox]').each(function (index,item) {
      var checkbox=item;
      var id = $(checkbox).data('_id');
      updateSelected('add', id, checkbox.name);
      this.checked = true;
    });
  }

  function unAllCkb(){
    $('tbody input[type=checkbox]').each(function (index,item) {
      var checkbox=item;
      var id = $(checkbox).data('_id');
      updateSelected('remove', id, checkbox.name);
      this.checked = false;
    });
  }
  var updateSelected = function (action, id, name) {
    if (action == 'add' && $scope.selected.indexOf(id) == -1) {
    $scope.selected.push(id);
    $scope.selectedTags.push(name);
  }
  if (action == 'remove' && $scope.selected.indexOf(id) != -1) {
    var idx = $scope.selected.indexOf(id);
    $scope.selected.splice(idx, 1);
    $scope.selectedTags.splice(idx,1);
    var CheckBox=document.getElementById("all");
     CheckBox.checked=false;
  }
  if ($scope.selected.length > 0) {
    $scope.filelist=true;
  } else {
    $scope.filelist=false;
  }
//alert($scope.selected);

}

  $scope.updateSelection = function ($event) {
    var checkbox = $event.target;
    var id = $(checkbox).data('_id');
    var action = (checkbox.checked ? 'add' : 'remove');
    updateSelected(action, id, checkbox.name);
  }
  $scope.isSelected = function(id){
         return $scope.selected.indexOf(id)>=0;
  }      

  $scope.my_tree_handler = function(branch) {

    $scope.output = branch.label;

    if (branch.data && branch.data.description) {
      $scope.output += '(' + branch.data.description + ')';
      return $scope.output;
    }
  };
  var treedata_avm = [
    {
      label: '进化基因组学和群体遗传学致病性链球菌',
      children: [
        {
          label: 'index.doc'
        }, {
          label: 'bg2.png'
        }
      ]
    }
  ];
  
  $scope.my_data = treedata_avm;
 
  $scope.showName = function(user) {
    return '新建文件夹'+ $scope.proFiles.id;
  };

  $scope.saveProFile = function(data, id) {
    //$scope.user not updated yet
    angular.extend(data, {id: id});
    console.log('Saving proFiles: ' + id);
    // return $http.post('/saveUser', data);
  };

  // remove user
  $scope.removeProFile = function(index) {
    $scope.proFiles.splice(index, 1);
  };

  // add user
  $scope.addProFile = function() {
    $scope.inserted = {
      id: $scope.proFiles.length+1,
      name: '',
      group: null,
      isNew: true
    };
    $scope.proFiles.push($scope.inserted);
  };

  // editable column
  // ----------------------------------- 

  // editable table
  // ----------------------------------- 

  // filter users to show
  $scope.filterProFile = function(user) {
    return proFile.isDeleted !== true;
  };

  // mark user as deleted
  $scope.deleteProFile = function(id) {
    var filtered = $filter('filter')($scope.proFiles, {id: id});
    if (filtered.length) {
      filtered[0].isDeleted = true;
    }
  };

  // cancel all changes
  $scope.cancel = function() {
    for (var i = $scope.proFiles.length; i--;) {
      var proFile = $scope.proFiles[i];
      // undelete
      if (proFile.isDeleted) {
        delete proFile.isDeleted;
      }
      // remove new 
      if (proFile.isNew) {
        $scope.proFiles.splice(i, 1);
      }
    }
  };
}]); 

App.controller('DatatableController', ['$scope', '$timeout', '$resource', '$http',function($scope, $timeout, $resource,$http) {

  $scope.my_tree_handler = function(branch) {

    $scope.output = branch.label;

    if (branch.data && branch.data.description) {
      $scope.output += '(' + branch.data.description + ')';
      return $scope.output;
    }
  };
  var basePath = 'data/';

  // onSelect event handlers
  var apple_selected = function(branch) {
    $scope.output = "APPLE! : " + branch.label;
    return $scope.output;
  };

  $scope.result = "result";

  $scope.organism = {};
  $scope.type = {};
  $scope.user = {};
  $scope.instrument = {};
  $scope.project = {};
  $scope.projects=[{Name:"Study"},{Name:"Experiment"},{Name:"Sample"},{Name:"Run"}];

  $http({
            method:"GET",
            url:"http://127.0.0.1:8001/organismlist/"
        })

        .success(
                function(response) {
                    $scope.organisms = response;
                    if($scope.organisms.length == 1){
                      $scope.moreorga = false;
                    }else{
                      $scope.moreorga = true;
                    }
                    if($scope.organisms.length<10){
                      $scope.showorga = false;
                    }else{
                      $scope.showorga = true;
                    }
                  }
                )
        .error(
               function() {
                        $scope.result = "fail";
                          }
                );

           
  $http({
            method:"GET",
            url:"http://127.0.0.1:8001/typelist/"
        })

        .success(
                function(response) {
                    $scope.types = response;
                    if($scope.types.length == 1){
                      $scope.moretype = false;
                    }else{
                      $scope.moretype = true;
                    }
                    if($scope.types.length<10){
                      $scope.showtype = false;
                    }else{
                      $scope.showtype = true;
                    }
                    }
                )
        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
    $http({
            method:"GET",
            url:"http://127.0.0.1:8001/userlist/"
        })

        .success(
                function(response) {
                    $scope.users = response;
                    if($scope.users.length == 1){
                      $scope.moreuser = false;
                    }else{
                      $scope.moreuser = true;
                    }
                    if($scope.users.length<10){
                      $scope.showuser = false;
                    }else{
                      $scope.showuser = true;
                    }
                    }
                )
        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
    $http({
            method:"GET",
            url:"http://127.0.0.1:8001/instrumentlist/"
        })

        .success(
                function(response) {
                    $scope.instruments = response;
                    if($scope.instruments.length ==1){
                      $scope.moreinst = false;
                    }else{
                      $scope.moreinst = true;
                    }
                    if($scope.instruments.length<10){
                      $scope.showinst = false;
                    }else{
                      $scope.showinst = true;
                    }
                    }
                )
        .error(
               function() {
                        $scope.result = "fail";
                          }
                );

  $scope.orgselectedTags = []; 
  
  var orgSelected = function(action,id,name){ 
    if(action == 'add' && $scope.selected.indexOf(id) == -1){ 
      $scope.orgselectedTags.push(name); 
    } 
    if(action == 'remove' && $scope.selected.indexOf(id)!=-1){ 
      var idx = $scope.selected.indexOf(id); 
      $scope.orgselectedTags.splice(idx,1); 
    } 
  } 
  
  $scope.orgSelection = function($event, id){ 
    var checkbox = $event.target; 
    var action = (checkbox.checked?'add':'remove'); 
    orgSelected(action,id,checkbox.name); 
  } 
  $scope.typeselectedTags = []; 
  
  var typeSelected = function(action,id,name){ 
    if(action == 'add' && $scope.selected.indexOf(id) == -1){ 
      $scope.typeselectedTags.push(name); 
    } 
    if(action == 'remove' && $scope.selected.indexOf(id)!=-1){ 
      var idx = $scope.selected.indexOf(id); 
      $scope.typeselectedTags.splice(idx,1); 
    } 
  } 
  
  $scope.typeSelection = function($event, id){ 
    var checkbox = $event.target; 
    var action = (checkbox.checked?'add':'remove'); 
    typeSelected(action,id,checkbox.name); 
  } 
  $scope.userselectedTags = []; 
  
  var userSelected = function(action,id,name){ 
    if(action == 'add' && $scope.selected.indexOf(id) == -1){ 
      $scope.userselectedTags.push(name); 
    } 
    if(action == 'remove' && $scope.selected.indexOf(id)!=-1){ 
      var idx = $scope.selected.indexOf(id); 
      $scope.userselectedTags.splice(idx,1); 
    } 
  } 
  
  $scope.userSelection = function($event, id){ 
    var checkbox = $event.target; 
    var action = (checkbox.checked?'add':'remove'); 
    userSelected(action,id,checkbox.name); 
  } 
  $scope.instselectedTags = []; 
  
  var instSelected = function(action,id,name){ 
    if(action == 'add' && $scope.selected.indexOf(id) == -1){ 
      $scope.instselectedTags.push(name); 
    } 
    if(action == 'remove' && $scope.selected.indexOf(id)!=-1){ 
      var idx = $scope.selected.indexOf(id); 
      $scope.instselectedTags.splice(idx,1); 
    } 
  } 
  
  $scope.instSelection = function($event, id){ 
    var checkbox = $event.target; 
    var action = (checkbox.checked?'add':'remove'); 
    userSelected(action,id,checkbox.name); 
  }
  $scope.isSelected = function(id){ 
    return $scope.selected.indexOf(id)>=0; 
  } 
    $scope.showorg = function () {
        
        console.log("hehe");
      }
}]);

App.controller('AbnTestController', ['$scope', '$timeout', '$resource', function($scope, $timeout, $resource) {

  $scope.my_tree_handler = function(branch) {

    $scope.output = branch.path;

    if (branch.data && branch.data.description) {
      $scope.output += '(' + branch.data.description + ')';
      return $scope.output;
    }
  };

  var basePath = 'server/editor/';

  // onSelect event handlers
  var apple_selected = function(branch) {
    $scope.output = "APPLE! : " + branch.label;
    return $scope.output;
  };

  var treedata_avm = [
  {
      label: "bg1.jpg",
      path: "data/bg1.jpg"
    },{
      label: "bg2.jpg",
      path: "data/bg2.jpg"
    }
  ];
  
  $scope.my_data = treedata_avm;
  $scope.try_changing_the_tree_data = function() {
    if ($scope.my_data === treedata_avm) {
      $scope.my_data = treedata_geography;
    } else {
      $scope.my_data = treedata_avm;
    }
    return $scope.my_data;
  };
  
  var tree;
  // This is our API control variable
  $scope.my_tree = tree = {};
  $scope.try_async_load = function() {
    
    $scope.my_data = [];
    $scope.doing_async = true;
    
    // Request tree data via $resource
    var remoteTree = $resource('server/treedata.json');
    
    return remoteTree.get(function(res){
      
      $scope.my_data = res.data;

      $scope.doing_async = false;
    
      return tree.expand_all();
    
    // we must return a promise so the plugin 
    // can watch when it's resolved
    }).$promise;
  };
 
  
}]);

/**=========================================================
 * Module: sidebar-menu.js
 * Handle sidebar collapsible elements
 =========================================================*/

App.controller('SidebarController', ['$rootScope', '$scope', '$state', '$http', '$timeout', 'Utils',
  function($rootScope, $scope, $state, $http, $timeout, Utils){

    var collapseList = [];

    // demo: when switch from collapse to hover, close all items
    $rootScope.$watch('app.layout.asideHover', function(oldVal, newVal){
      if ( newVal === false && oldVal === true) {
        closeAllBut(-1);
      }
    });

    // Check item and children active state
    var isActive = function(item) {

      if(!item) return;

      if( !item.sref || item.sref == '#') {
        var foundActive = false;
        angular.forEach(item.submenu, function(value, key) {
          if(isActive(value)) foundActive = true;
        });
        return foundActive;
      }
      else
        return $state.is(item.sref) || $state.includes(item.sref);
    };

    // Load menu from json file
    // ----------------------------------- 
    
    $scope.getMenuItemPropClasses = function(item) {
      return (item.heading ? 'nav-heading' : '') +
             (isActive(item) ? ' active' : '') ;
    };

    $scope.loadSidebarMenu = function() {

      var menuJson = 'server/sidebar-menu.json',
          menuURL  = menuJson + '?v=' + (new Date().getTime()); // jumps cache
      $http.get(menuURL)
        .success(function(items) {
           $scope.menuItems = items;
        })
        .error(function(data, status, headers, config) {
          alert('Failure loading menu');
        });
     };

     $scope.loadSidebarMenu();

    // Handle sidebar collapse items
    // ----------------------------------- 

    $scope.addCollapse = function($index, item) {
      collapseList[$index] = $rootScope.app.layout.asideHover ? true : !isActive(item);
    };

    $scope.isCollapse = function($index) {
      return (collapseList[$index]);
    };

    $scope.toggleCollapse = function($index, isParentItem) {


      // collapsed sidebar doesn't toggle drodopwn
      if( Utils.isSidebarCollapsed() || $rootScope.app.layout.asideHover ) return true;

      // make sure the item index exists
      if( angular.isDefined( collapseList[$index] ) ) {
        if ( ! $scope.lastEventFromChild ) {
          collapseList[$index] = !collapseList[$index];
          closeAllBut($index);
        }
      }
      else if ( isParentItem ) {
        closeAllBut(-1);
      }
      
      $scope.lastEventFromChild = isChild($index);

      return true;
    
    };

    function closeAllBut(index) {
      index += '';
      for(var i in collapseList) {
        if(index < 0 || index.indexOf(i) < 0)
          collapseList[i] = true;
      }
    }

    function isChild($index) {
      return (typeof $index === 'string') && !($index.indexOf('-') < 0);
    }

}]);

App.controller('TopbarController', ['$rootScope', '$scope', '$state', '$http', '$timeout', 'Utils',
  function($rootScope, $scope, $state, $http, $timeout, Utils){

    var collapseList = [];

    // demo: when switch from collapse to hover, close all items
    $rootScope.$watch('app.layout.asideHover', function(oldVal, newVal){
      if ( newVal === false && oldVal === true) {
        closeAllBut(-1);
      }
    });

    // Check item and children active state
    var isActive = function(item) {

      if(!item) return;

      if( !item.sref || item.sref == '#') {
        var foundActive = false;
        angular.forEach(item.submenu, function(value, key) {
          if(isActive(value)) foundActive = true;
        });
        return foundActive;
      }
      else
        return $state.is(item.sref) || $state.includes(item.sref);
    };

    // Load menu from json file
    // ----------------------------------- 
    
    $scope.getMenuItemPropClasses = function(item) {
      return (item.heading ? 'nav-heading' : '') +
             (isActive(item) ? ' active' : '') ;
    };

    $scope.loadSidebarMenu = function() {

      var menuJson = 'server/topbar-menu.json',
          menuURL  = menuJson + '?v=' + (new Date().getTime()); // jumps cache
      $http.get(menuURL)
        .success(function(items) {
           $scope.menuItems = items;
        })
        .error(function(data, status, headers, config) {
          alert('Failure loading menu');
        });
     };

     $scope.loadSidebarMenu();

    // Handle sidebar collapse items
    // ----------------------------------- 

    $scope.addCollapse = function($index, item) {
      collapseList[$index] = $rootScope.app.layout.asideHover ? true : !isActive(item);
    };

    $scope.isCollapse = function($index) {
      return (collapseList[$index]);
    };

    $scope.toggleCollapse = function($index, isParentItem) {


      // collapsed sidebar doesn't toggle drodopwn
      if( Utils.isSidebarCollapsed() || $rootScope.app.layout.asideHover ) return true;

      // make sure the item index exists
      if( angular.isDefined( collapseList[$index] ) ) {
        if ( ! $scope.lastEventFromChild ) {
          collapseList[$index] = !collapseList[$index];
          closeAllBut($index);
        }
      }
      else if ( isParentItem ) {
        closeAllBut(-1);
      }
      
      $scope.lastEventFromChild = isChild($index);

      return true;
    
    };

    function closeAllBut(index) {
      index += '';
      for(var i in collapseList) {
        if(index < 0 || index.indexOf(i) < 0)
          collapseList[i] = true;
      }
    }

    function isChild($index) {
      return (typeof $index === 'string') && !($index.indexOf('-') < 0);
    }

}]);
/**=========================================================
 * Module: sortable.js
 * Sortable controller
 =========================================================*/

App.controller('SortableController', ['$scope', function($scope) {
  'use strict';

  // Single List
  $scope.data1 = [
    { id: 1, name: 'Donald Hoffman' },
    { id: 2, name: 'Wallace Barrett' },
    { id: 3, name: 'Marsha Hicks' },
    { id: 4, name: 'Roland Brown' }
  ];

  $scope.add = function () {
    $scope.data1.push({id: $scope.data1.length + 1, name: 'Earl Knight'});
  };

  $scope.sortableCallback = function (sourceModel, destModel, start, end) {
    console.log(start + ' -> ' + end);
  };
  
  $scope.sortableOptions = {
      placeholder: '<div class="box-placeholder p0 m0"><div></div></div>',
      forcePlaceholderSize: true
  };

}]);

App.filter('propsFilter', function() {
  return function(items, props) {
    var out = [];

    if (angular.isArray(items)) {
      items.forEach(function(item) {
        var itemMatches = false;

        var keys = Object.keys(props);
        for (var i = 0; i < keys.length; i++) {
          var prop = keys[i];
          var text = props[prop].toLowerCase();
          if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
            itemMatches = true;
            break;
          }
        }

        if (itemMatches) {
          out.push(item);
        }
      });
    } else {
      // Let the output be the input untouched
      out = items;
    }

    return out;
  };
});
/**=========================================================
 * Module: upload.js
 =========================================================*/
 App.directive('fileModel', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;
            
            element.bind('change', function(){
                scope.$apply(function(){
                    modelSetter(scope, element[0].files[0]);
                });
            });
        }
    };
}]);
App.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file, uploadUrl){
        var fd = new FormData();
        fd.append('file', file);
        $http.post(uploadUrl, fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined},
        })
        .success(function(){
        })
        .error(function(){
        });
    }
}]);

App.controller('ProjectFileFormController', ['$scope', '$http', '$state','fileUpload' ,function($scope, $http, $state,fileUpload) {
// bind here all data from the form
  $scope.studyfile = {};
  // place the message if something goes wrong
  $scope.authMsg = '';
  $http({
            method:"POST",
            url:"http://127.0.0.1:8001/getaccount/",
        })

        .success(
                function(response) {

                    $scope.studyfile.Submitter= response;

                    }
                )

        .error(
               function() {
                        $scope.result = "fail";
                          }
                );

$scope.file = function(){
        
        $scope.studyfile.FileName = document.getElementById("uploadFileName").value;
        $scope.studyfile.Study = document.getElementById("uploadStudyName").value;
        if($scope.studyfile.Study==""){
          alert("请选择所属项目")
        }else{
    $http({
            method:"POST",
            url:"http://127.0.0.1:8001/studyfileadd/",
            data:$scope.studyfile
        })
        .success(
                function(response) {
                        if(response == 1){
                            console.log("新建成功");
                            $scope.result02 = "success";
                        }
                        else{
                          console.log("重复新建");
                            $scope.result02 = "fail";
                        }
                    }
                )


        .error(
               function() {
                        $scope.result02 = "fail";
                          }
                );
      }
      };

}]);
App.controller('StudyAddController', ['$scope', '$http', '$state','toaster',function($scope, $http, $state,toaster) {

  // bind here all data from the form
  $scope.study = {};
  // place the message if something goes wrong
  $scope.authMsg = '';
  $http({
            method:"POST",
            url:"http://127.0.0.1:8001/getaccount/"
        })

        .success(
                function(response) {
                    $scope.study.Submitter = response;
                    }
                )

        .error(
               function() {
                        $scope.result = "fail";
                          }

                );

  $scope.studyadd = function() {

    if($scope.studyAddForm.$valid) {
      $scope.study.Organisms=document.getElementById("stuorganism").value;
      $scope.study.Type=document.getElementById("stutype").value;
      $scope.study.Project=document.getElementById("stuproject").value;
      if($scope.study.Organisms == ''){
        alert("请选择组织");
      }else if($scope.study.Type == ''){
        alert("请选择类型");
      }else if($scope.study.Project == "Study"){
          $http({
              method:"POST",
              url:"http://127.0.0.1:8001/studyadd/",
              data:$scope.study
          })

          .success(
                  function(response) {
                     if(response == 1){
                          $scope.toaster = {
                              type:  'success',
                              text:  '项目建立成功'
                          };
                          toaster.pop($scope.toaster.type, $scope.toaster.text);
                          $scope.result = "success";
                        }
                        else{
                          alert("该项目已经存在，请重新输入")
                          $scope.result = "fail";
                        }
                      }
                  )

          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  );
        }else if($scope.study.Project == "Experiment"){
          $http({
              method:"POST",
              url:"http://127.0.0.1:8001/experimentadd/",
              data:$scope.experiment
          })

          .success(
                  function(response) {
                     if(response == 1){
                          $scope.toaster = {
                              type:  'success',
                              text:  '项目建立成功'
                          };
                          toaster.pop($scope.toaster.type, $scope.toaster.text);
                          $scope.result = "success";
                        }
                        else{
                          alert("该项目已经存在，请重新输入")
                          $scope.result = "fail";
                        }
                      }
                  )

          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  );
        }else if($scope.study.Project == "Sample"){
          $http({
              method:"POST",
              url:"http://127.0.0.1:8001/sampleadd/",
              data:$scope.sample
          })

          .success(
                  function(response) {
                     if(response == 1){
                          $scope.toaster = {
                              type:  'success',
                              text:  '项目建立成功'
                          };
                          toaster.pop($scope.toaster.type, $scope.toaster.text);
                          $scope.result = "success";
                        }
                        else{
                          alert("该项目已经存在，请重新输入")
                          $scope.result = "fail";
                        }
                      }
                  )

          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  );
        }else if($scope.study.Project == "Run"){
          $http({
              method:"POST",
              url:"http://127.0.0.1:8001/runsadd/",
              data:$scope.runs
          })

          .success(
                  function(response) {
                     if(response == 1){
                          $scope.toaster = {
                              type:  'success',
                              text:  '项目建立成功'
                          };
                          toaster.pop($scope.toaster.type, $scope.toaster.text);
                          $scope.result = "success";
                        }
                        else{
                          alert("该项目已经存在，请重新输入")
                          $scope.result = "fail";
                        }
                      }
                  )

          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  );
        }
    }else {
      // set as dirty if the user click directly to login so we show the validation messages
      $scope.studyAddForm.account_name.$dirty = true;
      $scope.studyAddForm.account_description.$dirty = true;
    }
  };
}]);
App.controller('FileUploadController', ['$scope', 'FileUploader','fileUpload','$http', function($scope, FileUploader,fileUpload,$http) {
    
    var uploader = $scope.uploader = new FileUploader({
        url: 'server/upload.php'
    });

    // FILTERS

    uploader.filters.push({
        name: 'customFilter',
        fn: function(item /*{File|FileLikeObject}*/, options) {
            return this.queue.length < 10;
        }
    });
    $scope.uploadFile = function() {
        var file = $scope.myFile;
        console.log('file is ' );
        console.dir(file);
        var uploadUrl = "http://127.0.0.1:8001/studyfileupload/";
        fileUpload.uploadFileToUrl(file, uploadUrl);
        $scope.isSuccess=true;
      }
    // CALLBACKS

    uploader.onWhenAddingFileFailed = function(item /*{File|FileLikeObject}*/, filter, options) {
        console.info('onWhenAddingFileFailed', item, filter, options);
    };
    uploader.onAfterAddingFile = function(fileItem) {
        console.info('onAfterAddingFile', fileItem);
    };
    uploader.onAfterAddingAll = function(addedFileItems) {
        console.info('onAfterAddingAll', addedFileItems);
    };
    uploader.onBeforeUploadItem = function(item) {
        console.info('onBeforeUploadItem', item);
    };
    uploader.onProgressItem = function(fileItem, progress) {
        console.info('onProgressItem', fileItem, progress);
    };
    uploader.onProgressAll = function(progress) {
        console.info('onProgressAll', progress);
    };
    uploader.onSuccessItem = function(fileItem, response, status, headers) {
        console.info('onSuccessItem', fileItem, response, status, headers);
    };
    uploader.onErrorItem = function(fileItem, response, status, headers) {
        console.info('onErrorItem', fileItem, response, status, headers);
    };
    uploader.onCancelItem = function(fileItem, response, status, headers) {
        console.info('onCancelItem', fileItem, response, status, headers);
    };
    uploader.onCompleteItem = function(fileItem, response, status, headers) {
        console.info('onCompleteItem', fileItem, response, status, headers);
    };
    uploader.onCompleteAll = function() {
        console.info('onCompleteAll');
    };

    console.info('uploader', uploader);
}]);
App.controller('NotifyDemoCtrl', ['$scope', 'Notify', '$timeout', function AlertDemoCtrl($scope, Notify, $timeout) {

  $scope.msgHtml = "<em class='fa fa-check'></em> Message with icon..";

  $scope.notifyMsg = "Some messages here..";
  $scope.notifyOpts = {
    status: 'danger',
    pos: 'bottom-center'
  };

  // Service usage example
  $timeout(function(){
    
    Notify.alert( 
        'This is a custom message from notify..', 
        {status: 'success'}
    );
  
  }, 500);
}]);
App.controller('PersonalProjectDataController', ['$scope','$timeout', '$resource', '$http',function($scope,$timeout, $resource,$http) {

  $scope.result = "result";
  $scope.inputdata={};
  $scope.study = {};
  $scope.experiment = {};
  $scope.sample = {};
  $scope.run = {};
    $http({
            method:"GET",
            url:"http://127.0.0.1:8001/studylist/"
        })

        .success(
                function(response) {
                    $scope.studys = response;
                    }
                )
        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
        
      $http({
                method:"GET",
                url:"http://127.0.0.1:8001/experimentlist/"
            })

            .success(
                    function(response) {
                        $scope.experiments = response;
                        }
                    )
            .error(
                   function() {
                            $scope.result = "fail";
                              }
                    );
        
        
    
      $http({
              method:"GET",
              url:"http://127.0.0.1:8001/samplelist/"
          })

          .success(
                  function(response) {
                      $scope.samples = response;
                      }
                  )
          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  );
        
      $http({
              method:"GET",
              url:"http://127.0.0.1:8001/runslist/"
          })

          .success(
                  function(response) {
                      $scope.runs = response;
                      }
                  )
          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  ); 

}]);
App.controller('ProjectDataController', ['$scope',"$stateParams",'$timeout', '$resource', '$http','DTOptionsBuilder', 'DTColumnDefBuilder',
  function($scope,$stateParams,$timeout, $resource,$http,DTOptionsBuilder, DTColumnDefBuilder) {

  $scope.dtOptions = DTOptionsBuilder.newOptions().withPaginationType('full_numbers');
  $scope.dtColumnDefs = [
      DTColumnDefBuilder.newColumnDef(0).notSortable(),
      DTColumnDefBuilder.newColumnDef(1).notSortable(),
      DTColumnDefBuilder.newColumnDef(2),
      DTColumnDefBuilder.newColumnDef(3),
      DTColumnDefBuilder.newColumnDef(4).notSortable()
  ];
  $scope.result = "result";
  $scope.inputdata={};
  $scope.projects={};

    if($stateParams.typeName=="studys"){
      $http({
              method:"GET",
              url:"http://127.0.0.1:8001/studylist/"
          })

          .success(
                  function(response) {
                      $scope.projects = response;
                      }
                  )
          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  );
          $scope.typesearch = function(study){
            $scope.inputdata.keyword=study;
            console.log($scope.inputdata.keyword);
            $http({
                method:"POST",
                url:"http://127.0.0.1:8001/studysearch/",
                data:$scope.inputdata
            })


            .success(
                    function(response) {
                        return $scope.projects = response;
                        }
                    )


            .error(
                   function() {
                            $scope.result = "fail";
                              }
                    );
            $scope.listtag=true;
          };
    }
    else if($stateParams.typeName=="experiments"){
      $http({
                method:"GET",
                url:"http://127.0.0.1:8001/experimentlist/"
            })

            .success(
                    function(response) {
                        $scope.projects = response;
                        }
                    )
            .error(
                   function() {
                            $scope.result = "fail";
                              }
                    );
      $scope.typesearch = function(experiment){
        $scope.inputdata.keyword=experiment;
        console.log($scope.inputdata.keyword);
        $http({
            method:"POST",
            url:"http://127.0.0.1:8001/experimentsearch/",
            data:$scope.inputdata
        })


        .success(
                function(response) {
                    return $scope.projects = response;
                    }
                )


        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
      };
      $scope.listtag=true;
    }
    else if($stateParams.typeName=="samples"){
      $http({
              method:"GET",
              url:"http://127.0.0.1:8001/samplelist/"
          })

          .success(
                  function(response) {
                      $scope.projects = response;
                      }
                  )
          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  );
      $scope.typesearch = function(sample){
        $scope.inputdata.keyword=sample;
        console.log($scope.inputdata.keyword);
        $http({
            method:"POST",
            url:"http://127.0.0.1:8001/samplesearch/",
            data:$scope.inputdata
        })


        .success(
                function(response) {
                    return $scope.projects = response;
                    }
                )


        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
        $scope.listtag=true;
      };
    }
    else if($stateParams.typeName=="runs"){
      $http({
              method:"GET",
              url:"http://127.0.0.1:8001/runslist/"
          })

          .success(
                  function(response) {
                      $scope.projects = response;
                      }
                  )
          .error(
                 function() {
                          $scope.result = "fail";
                            }
                  ); 
      $scope.runssearch = function(runs){
        $scope.inputdata.keyword=runs;
        console.log($scope.inputdata.keyword);
        $http({
            method:"POST",
            url:"http://127.0.0.1:8001/runssearch/",
            data:$scope.inputdata
        })


        .success(
                function(response) {
                    return $scope.projects = response;
                    }
                )


        .error(
               function() {
                        $scope.result = "fail";
                          }
                );
        $scope.listtag=true;
      };
    }
  $scope.selected = [];
  $scope.selectedTags = [];

  $scope.allCheckOrNot=function($event){
    var checkbox = $event.target;
    if(checkbox.checked){
      allCkb();
    }else{
      unAllCkb()
    }
  }
  function allCkb() {
    $('tbody input[type=checkbox]').each(function (index,item) {
      var checkbox=item;
      var id = $(checkbox).data('_id');
      updateSelected('add', id, checkbox.name);
      this.checked = true;
    });
  }

  function unAllCkb(){
    $('tbody input[type=checkbox]').each(function (index,item) {
      var checkbox=item;
      var id = $(checkbox).data('_id');
      updateSelected('remove', id, checkbox.name);
      this.checked = false;
    });
  }
  var updateSelected = function (action, id, name) {
    if (action == 'add' && $scope.selected.indexOf(id) == -1) {
    $scope.selected.push(id);
    $scope.selectedTags.push(name);
  }
  if (action == 'remove' && $scope.selected.indexOf(id) != -1) {
    var idx = $scope.selected.indexOf(id);
    $scope.selected.splice(idx, 1);
    $scope.selectedTags.splice(idx,1);
    var CheckBox=document.getElementById("all");
     CheckBox.checked=false;
  }
  if ($scope.selected.length > 0) {
    $scope.datadown=true;
  } else {
    $scope.datadown=false;
  }
//alert($scope.selected);
}
  $scope.updateSelection = function ($event) {
    var checkbox = $event.target;
    var id = $(checkbox).data('_id');
    var action = (checkbox.checked ? 'add' : 'remove');
    updateSelected(action, id, checkbox.name);
  }
  $scope.isSelected = function(id){
         return $scope.selected.indexOf(id)>=0;
  }
}]);


/**=========================================================
 * Module: anchor.js
 * Disables null anchor behavior
 =========================================================*/
  App.directive('contextMenu', ['$document','ContextMenuService',
    function($document, ContextMenuService) {
      return {
        restrict: 'A',
        scope: {
          'callback': '&contextMenu',
          'disabled': '&contextMenuDisabled',
          'closeCallback': '&contextMenuClose'
        },
        link: function($scope, $element, $attrs) {
          var opened = false;

          function open(event, menuElement) {
            menuElement.addClass('open');

            var doc = $document[0].documentElement;
            var docLeft = (window.pageXOffset || doc.scrollLeft) -
                          (doc.clientLeft || 0),
                docTop = (window.pageYOffset || doc.scrollTop) -
                         (doc.clientTop || 0),
                elementWidth = menuElement[0].scrollWidth,
                elementHeight = menuElement[0].scrollHeight;
            var docWidth = doc.clientWidth + docLeft,
              docHeight = doc.clientHeight + docTop,
              totalWidth = elementWidth + event.pageX,
              totalHeight = elementHeight + event.pageY,
              left = Math.max(event.pageX - docLeft, 0),
              top = Math.max(event.pageY - docTop, 0);

            if (totalWidth > docWidth) {
              left = left - (totalWidth - docWidth);
            }

            if (totalHeight > docHeight) {
              top = top - (totalHeight - docHeight);
            }

            menuElement.css('top', top + 'px');
            menuElement.css('left', left + 'px');
            opened = true;
          }

          function close(menuElement) {
            menuElement.removeClass('open');

            if (opened) {
              $scope.closeCallback();
            }

            opened = false;
          }

          $element.bind('contextmenu', function(event) {
            if (!$scope.disabled()) {
              if (ContextMenuService.menuElement !== null) {
                close(ContextMenuService.menuElement);
              }
              ContextMenuService.menuElement = angular.element(
                document.getElementById($attrs.target)
              );
              ContextMenuService.element = event.target;
              //console.log('set', ContextMenuService.element);

              event.preventDefault();
              event.stopPropagation();
              $scope.$apply(function() {
                $scope.callback({ $event: event });
              });
              $scope.$apply(function() {
                open(event, ContextMenuService.menuElement);
              });
            }
          });

          function handleKeyUpEvent(event) {
            //console.log('keyup');
            if (!$scope.disabled() && opened && event.keyCode === 27) {
              $scope.$apply(function() {
                close(ContextMenuService.menuElement);
              });
            }
          }

          function handleClickEvent(event) {
            if (!$scope.disabled() &&
              opened &&
              (event.button !== 2 ||
               event.target !== ContextMenuService.element)) {
              $scope.$apply(function() {
                close(ContextMenuService.menuElement);
              });
            }
          }

          $document.bind('keyup', handleKeyUpEvent);
          // Firefox treats a right-click as a click and a contextmenu event
          // while other browsers just treat it as a contextmenu event
          $document.bind('click', handleClickEvent);
          $document.bind('contextmenu', handleClickEvent);

          $scope.$on('$destroy', function() {
            //console.log('destroy');
            $document.unbind('keyup', handleKeyUpEvent);
            $document.unbind('click', handleClickEvent);
            $document.unbind('contextmenu', handleClickEvent);
          });
        }
      };
    }
  ]);


App.directive('href', function() {

  return {
    restrict: 'A',
    compile: function(element, attr) {
        return function(scope, element) {
          if(attr.ngClick || attr.href === '' || attr.href === '#'){
            if( !element.hasClass('dropdown-toggle') )
              element.on('click', function(e){
                e.preventDefault();
                e.stopPropagation();
              });
          }
        };
      }
   };
});
/**=========================================================
 * Module: animate-enabled.js
 * Enable or disables ngAnimate for element with directive
 =========================================================*/

App.directive("animateEnabled", ["$animate", function ($animate) {
  return {
    link: function (scope, element, attrs) {
      scope.$watch(function () {
        return scope.$eval(attrs.animateEnabled, scope);
      }, function (newValue) {
        $animate.enabled(!!newValue, element);
      });
    }
  };
}]);
/**=========================================================
 * Module: chart.js
 * Wrapper directive for chartJS. 
 * Based on https://gist.github.com/AndreasHeiberg/9837868
 =========================================================*/

var ChartJS = function (type) {
    return {
        restrict: "A",
        scope: {
            data: "=",
            options: "=",
            id: "@",
            width: "=",
            height: "=",
            resize: "=",
            chart: "@",
            segments: "@",
            responsive: "=",
            tooltip: "=",
            legend: "="
        },
        link: function ($scope, $elem) {
            var ctx = $elem[0].getContext("2d");
            var autosize = false;

            $scope.size = function () {
                if ($scope.width <= 0) {
                    $elem.width($elem.parent().width());
                    ctx.canvas.width = $elem.width();
                } else {
                    ctx.canvas.width = $scope.width || ctx.canvas.width;
                    autosize = true;
                }

                if($scope.height <= 0){
                    $elem.height($elem.parent().height());
                    ctx.canvas.height = ctx.canvas.width / 2;
                } else {
                    ctx.canvas.height = $scope.height || ctx.canvas.height;
                    autosize = true;
                }
            };

            $scope.$watch("data", function (newVal, oldVal) {
                if(chartCreated)
                    chartCreated.destroy();

                // if data not defined, exit
                if (!newVal) {
                    return;
                }
                if ($scope.chart) { type = $scope.chart; }

                if(autosize){
                    $scope.size();
                    chart = new Chart(ctx);
                }

                if($scope.responsive || $scope.resize)
                    $scope.options.responsive = true;

                if($scope.responsive !== undefined)
                    $scope.options.responsive = $scope.responsive;

                chartCreated = chart[type]($scope.data, $scope.options);
                chartCreated.update();
                if($scope.legend)
                    angular.element($elem[0]).parent().after( chartCreated.generateLegend() );
            }, true);

            $scope.$watch("tooltip", function (newVal, oldVal) {
                if (chartCreated)
                    chartCreated.draw();
                if(newVal===undefined || !chartCreated.segments)
                    return;
                if(!isFinite(newVal) || newVal >= chartCreated.segments.length || newVal < 0)
                    return;
                var activeSegment = chartCreated.segments[newVal];
                activeSegment.save();
                activeSegment.fillColor = activeSegment.highlightColor;
                chartCreated.showTooltip([activeSegment]);
                activeSegment.restore();
            }, true);

            $scope.size();
            var chart = new Chart(ctx);
            var chartCreated;
        }
    };
};

/* Aliases for various chart types */
App.directive("chartjs",       function () { return ChartJS(); });
App.directive("linechart",     function () { return ChartJS("Line"); });
App.directive("barchart",      function () { return ChartJS("Bar"); });
App.directive("radarchart",    function () { return ChartJS("Radar"); });
App.directive("polarchart",    function () { return ChartJS("PolarArea"); });
App.directive("piechart",      function () { return ChartJS("Pie"); });
App.directive("doughnutchart", function () { return ChartJS("Doughnut"); });
App.directive("donutchart",    function () { return ChartJS("Doughnut"); });

/**=========================================================
 * Module: classy-loader.js
 * Enable use of classyloader directly from data attributes
 =========================================================*/

App.directive('classyloader', ["$timeout", "Utils", function($timeout, Utils) {
  'use strict';

  var $scroller       = $(window),
      inViewFlagClass = 'js-is-in-view'; // a classname to detect when a chart has been triggered after scroll

  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      // run after interpolation  
      $timeout(function(){
  
        var $element = $(element),
            options  = $element.data();
        
        // At lease we need a data-percentage attribute
        if(options) {
          if( options.triggerInView ) {

            $scroller.scroll(function() {
              checkLoaderInVIew($element, options);
            });
            // if the element starts already in view
            checkLoaderInVIew($element, options);
          }
          else
            startLoader($element, options);
        }

      }, 0);

      function checkLoaderInVIew(element, options) {
        var offset = -20;
        if( ! element.hasClass(inViewFlagClass) &&
            Utils.isInView(element, {topoffset: offset}) ) {
          startLoader(element, options);
        }
      }
      function startLoader(element, options) {
        element.ClassyLoader(options).addClass(inViewFlagClass);
      }
    }
  };
}]);

/**=========================================================
 * Module: clear-storage.js
 * Removes a key from the browser storage via element click
 =========================================================*/

App.directive('resetKey',  ['$state','$rootScope', function($state, $rootScope) {
  'use strict';

  return {
    restrict: 'A',
    scope: {
      resetKey: '='
    },
    link: function(scope, element, attrs) {
      
      scope.resetKey = attrs.resetKey;

    },
    controller: ["$scope", "$element", function($scope, $element) {
    
      $element.on('click', function (e) {
          e.preventDefault();

          if($scope.resetKey) {
            delete $rootScope.$storage[$scope.resetKey];
            $state.go($state.current, {}, {reload: true});
          }
          else {
            $.error('No storage key specified for reset.');
          }
      });

    }]

  };

}]);
/**=========================================================
 * Module: filestyle.js
 * Initializes the fielstyle plugin
 =========================================================*/

App.directive('filestyle', function() {
  return {
    restrict: 'A',
    controller: ["$scope", "$element", function($scope, $element) {
      var options = $element.data();
      
      // old usage support
        options.classInput = $element.data('classinput') || options.classInput;
      
      $element.filestyle(options);
    }]
  };
});

/**=========================================================
 * Module: flatdoc.js
 * Creates the flatdoc markup and initializes the plugin
 =========================================================*/

App.directive('flatdoc', ['$location', function($location) {
  return {
    restrict: "EA",
    template: "<div role='flatdoc'><div role='flatdoc-menu'></div><div role='flatdoc-content'></div></div>",
    link: function(scope, element, attrs) {

      Flatdoc.run({
        fetcher: Flatdoc.file(attrs.src)
      });
      
      var $root = $('html, body');
      $(document).on('flatdoc:ready', function() {
        var docMenu = $('[role="flatdoc-menu"]');
        docMenu.find('a').on('click', function(e) {
          e.preventDefault(); e.stopPropagation();
          
          var $this = $(this);
          
          docMenu.find('a.active').removeClass('active');
          $this.addClass('active');

          $root.animate({
                scrollTop: $(this.getAttribute('href')).offset().top - ($('.topnavbar').height() + 10)
            }, 800);
        });

      });
    }
  };

}]);
/**=========================================================
 * Module: flot.js
 * Initializes the Flot chart plugin and handles data refresh
 =========================================================*/

App.directive('flot', ['$http', '$timeout', function($http, $timeout) {
  'use strict';
  return {
    restrict: 'EA',
    template: '<div></div>',
    scope: {
      dataset: '=?',
      options: '=',
      series: '=',
      callback: '=',
      src: '='
    },
    link: linkFunction
  };
  
  function linkFunction(scope, element, attributes) {
    var height, plot, plotArea, width;
    var heightDefault = 220;

    plot = null;

    width = attributes.width || '100%';
    height = attributes.height || heightDefault;

    plotArea = $(element.children()[0]);
    plotArea.css({
      width: width,
      height: height
    });

    function init() {
      var plotObj;
      if(!scope.dataset || !scope.options) return;
      plotObj = $.plot(plotArea, scope.dataset, scope.options);
      scope.$emit('plotReady', plotObj);
      if (scope.callback) {
        scope.callback(plotObj, scope);
      }

      return plotObj;
    }

    function onDatasetChanged(dataset) {
      if (plot) {
        plot.setData(dataset);
        plot.setupGrid();
        return plot.draw();
      } else {
        plot = init();
        onSerieToggled(scope.series);
        return plot;
      }
    }
    scope.$watchCollection('dataset', onDatasetChanged, true);

    function onSerieToggled (series) {
      if( !plot || !series ) return;
      var someData = plot.getData();
      for(var sName in series) {
        angular.forEach(series[sName], toggleFor(sName));
      }
      
      plot.setData(someData);
      plot.draw();
      
      function toggleFor(sName) {
        return function (s, i){
          if(someData[i] && someData[i][sName])
            someData[i][sName].show = s;
        };
      }
    }
    scope.$watch('series', onSerieToggled, true);
    
    function onSrcChanged(src) {

      if( src ) {

        $http.get(src)
          .success(function (data) {

            $timeout(function(){
              scope.dataset = data;
            });

        }).error(function(){
          $.error('Flot chart: Bad request.');
        });
        
      }
    }
    scope.$watch('src', onSrcChanged);
  }

}]);

/**=========================================================
 * Module: form-wizard.js
 * Handles form wizard plugin and validation
 =========================================================*/

App.directive('formWizard', ["$parse", function($parse){
  'use strict';

  return {
    restrict: 'A',
    scope: true,
    link: function(scope, element, attribute) {
      var validate = $parse(attribute.validateSteps)(scope),
          wiz = new Wizard(attribute.steps, !!validate, element);
      scope.wizard = wiz.init();

    }
  };

  function Wizard (quantity, validate, element) {
    
    var self = this;
    self.quantity = parseInt(quantity,10);
    self.validate = validate;
    self.element = element;
    
    self.init = function() {
      self.createsteps(self.quantity);
      self.go(1); // always start at fist step
      return self;
    };

    self.go = function(step) {
      
      if ( angular.isDefined(self.steps[step]) ) {

        if(self.validate && step !== 1) {
          var form = $(self.element),
              group = form.children().children('div').get(step - 2);

          if (false === form.parsley().validate( group.id )) {
            return false;
          }
        }

        self.cleanall();
        self.steps[step] = true;
      }
    };

    self.active = function(step) {
      return !!self.steps[step];
    };

    self.cleanall = function() {
      for(var i in self.steps){
        self.steps[i] = false;
      }
    };

    self.createsteps = function(q) {
      self.steps = [];
      for(var i = 1; i <= q; i++) self.steps[i] = false;
    };

  }

}]);

/**=========================================================
 * Module: fullscreen.js
 * Toggle the fullscreen mode on/off
 =========================================================*/

App.directive('toggleFullscreen', function() {
  'use strict';

  return {
    restrict: 'A',
    link: function(scope, element, attrs) {

      element.on('click', function (e) {
          e.preventDefault();

          if (screenfull.enabled) {
            
            screenfull.toggle();
            
            // Switch icon indicator
            if(screenfull.isFullscreen)
              $(this).children('em').removeClass('fa-expand').addClass('fa-compress');
            else
              $(this).children('em').removeClass('fa-compress').addClass('fa-expand');

          } else {
            $.error('Fullscreen not enabled');
          }

      });
    }
  };

});


/**=========================================================
 * Module: load-css.js
 * Request and load into the current page a css file
 =========================================================*/

App.directive('loadCss', function() {
  'use strict';

  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      element.on('click', function (e) {
          if(element.is('a')) e.preventDefault();
          var uri = attrs.loadCss,
              link;

          if(uri) {
            link = createLink(uri);
            if ( !link ) {
              $.error('Error creating stylesheet link element.');
            }
          }
          else {
            $.error('No stylesheet location defined.');
          }

      });

    }
  };

  function createLink(uri) {
    var linkId = 'autoloaded-stylesheet',
        oldLink = $('#'+linkId).attr('id', linkId + '-old');

    $('head').append($('<link/>').attr({
      'id':   linkId,
      'rel':  'stylesheet',
      'href': uri
    }));

    if( oldLink.length ) {
      oldLink.remove();
    }

    return $('#'+linkId);
  }


});
/**=========================================================
 * Module: masked,js
 * Initializes the masked inputs
 =========================================================*/

App.directive('masked', function() {
  return {
    restrict: 'A',
    controller: ["$scope", "$element", function($scope, $element) {
      var $elem = $($element);
      if($.fn.inputmask)
        $elem.inputmask();
    }]
  };
});

/**=========================================================
 * Module: morris.js
 * AngularJS Directives for Morris Charts
 =========================================================*/

(function() {
    "use strict";

    App.directive('morrisBar',   morrisChart('Bar')   );
    App.directive('morrisDonut', morrisChart('Donut') );
    App.directive('morrisLine',  morrisChart('Line')  );
    App.directive('morrisArea',  morrisChart('Area')  );

    function morrisChart(type) {
      return function () {
        return {
          restrict: 'EA',
          scope: {
            morrisData: '=',
            morrisOptions: '='
          },
          link: function($scope, elem, attrs) {
            // start ready to watch for changes in data
            $scope.$watch("morrisData", function(newVal, oldVal) {
              if (newVal) {
                $scope.morrisInstance.setData(newVal);
                $scope.morrisInstance.redraw();
              }
            }, true);
            // the element that contains the chart
            $scope.morrisOptions.element = elem;
            // If data defined copy to options
            if($scope.morrisData)
              $scope.morrisOptions.data = $scope.morrisData;
            // Init chart
            $scope.morrisInstance = new Morris[type]($scope.morrisOptions);

          }
        }
      }
    }

})();

/**=========================================================
 * Module: navbar-search.js
 * Navbar search toggler * Auto dismiss on ESC key
 =========================================================*/

App.directive('searchOpen', ['navSearch', function(navSearch) {
  'use strict';

  return {
    restrict: 'A',
    controller: ["$scope", "$element", function($scope, $element) {
      $element
        .on('click', function (e) { e.stopPropagation(); })
        .on('click', navSearch.toggle);
    }]
  };

}]).directive('searchDismiss', ['navSearch', function(navSearch) {
  'use strict';

  var inputSelector = '.navbar-form input[type="text"]';

  return {
    restrict: 'A',
    controller: ["$scope", "$element", function($scope, $element) {

      $(inputSelector)
        .on('click', function (e) { e.stopPropagation(); })
        .on('keyup', function(e) {
          if (e.keyCode == 27) // ESC
            navSearch.dismiss();
        });
        
      // click anywhere closes the search
      $(document).on('click', navSearch.dismiss);
      // dismissable options
      $element
        .on('click', function (e) { e.stopPropagation(); })
        .on('click', navSearch.dismiss);
    }]
  };

}]);


/**=========================================================
 * Module: notify.js
 * Directive for notify plugin
 =========================================================*/

App.directive('notify', ["$window", "Notify", function($window, Notify){

  return {
    restrict: 'A',
    scope: {
        options: '=',
        message: '='
    },
    link: function (scope, element, attrs) {
      
      element.on('click', function (e) {
        e.preventDefault();
        Notify.alert(scope.message, scope.options);
      });

    }
  };

}]);


/**=========================================================
 * Module: now.js
 * Provides a simple way to display the current time formatted
 =========================================================*/

App.directive("now", ['dateFilter', '$interval', function(dateFilter, $interval){
    return {
      restrict: 'E',
      link: function(scope, element, attrs){
        
        var format = attrs.format;

        function updateTime() {
          var dt = dateFilter(new Date(), format);
          element.text(dt);
        }

        updateTime();
        $interval(updateTime, 1000);
      }
    };
}]);
/**=========================================================
 * Module panel-tools.js
 * Directive tools to control panels. 
 * Allows collapse, refresh and dismiss (remove)
 * Saves panel state in browser storage
 =========================================================*/

App.directive('paneltool', ["$compile", "$timeout", function($compile, $timeout){
  var templates = {
    /* jshint multistr: true */
    collapse:"<a href='#' panel-collapse='' tooltip='Collapse Panel' ng-click='{{panelId}} = !{{panelId}}'> \
                <em ng-show='{{panelId}}' class='fa fa-plus'></em> \
                <em ng-show='!{{panelId}}' class='fa fa-minus'></em> \
              </a>",
    dismiss: "<a href='#' panel-dismiss='' tooltip='Close Panel'>\
               <em class='fa fa-times'></em>\
             </a>",
    refresh: "<a href='#' panel-refresh='' data-spinner='{{spinner}}' tooltip='Refresh Panel'>\
               <em class='fa fa-refresh'></em>\
             </a>"
  };

  function getTemplate( elem, attrs ){
    var temp = '';
    attrs = attrs || {};
    if(attrs.toolCollapse)
      temp += templates.collapse.replace(/{{panelId}}/g, (elem.parent().parent().attr('id')) );
    if(attrs.toolDismiss)
      temp += templates.dismiss;
    if(attrs.toolRefresh)
      temp += templates.refresh.replace(/{{spinner}}/g, attrs.toolRefresh);
    return temp;
  }
  
  return {
    restrict: 'E',
    scope: false,
    link: function (scope, element, attrs) {

      var tools = scope.panelTools || attrs;
  
      $timeout(function() {
        element.html(getTemplate(element, tools )).show();
        $compile(element.contents())(scope);
        
        element.addClass('pull-right');
      });

    }
  };
}])
/**=========================================================
 * Dismiss panels * [panel-dismiss]
 =========================================================*/
.directive('panelDismiss', ["$q", "Utils", function($q, Utils){
  'use strict';
  return {
    restrict: 'A',
    controller: ["$scope", "$element", function ($scope, $element) {
      var removeEvent   = 'panel-remove',
          removedEvent  = 'panel-removed';

      $element.on('click', function () {

        // find the first parent panel
        var parent = $(this).closest('.panel');

        removeElement();

        function removeElement() {
          var deferred = $q.defer();
          var promise = deferred.promise;
          
          // Communicate event destroying panel
          $scope.$emit(removeEvent, parent.attr('id'), deferred);
          promise.then(destroyMiddleware);
        }

        // Run the animation before destroy the panel
        function destroyMiddleware() {
          if(Utils.support.animation) {
            parent.animo({animation: 'bounceOut'}, destroyPanel);
          }
          else destroyPanel();
        }

        function destroyPanel() {

          var col = parent.parent();
          parent.remove();
          // remove the parent if it is a row and is empty and not a sortable (portlet)
          col
            .filter(function() {
            var el = $(this);
            return (el.is('[class*="col-"]:not(.sortable)') && el.children('*').length === 0);
          }).remove();

          // Communicate event destroyed panel
          $scope.$emit(removedEvent, parent.attr('id'));

        }
      });
    }]
  };
}])
/**=========================================================
 * Collapse panels * [panel-collapse]
 =========================================================*/
.directive('panelCollapse', ['$timeout', function($timeout){
  'use strict';
  
  var storageKeyName = 'panelState',
      storage;
  
  return {
    restrict: 'A',
    scope: false,
    controller: ["$scope", "$element", function ($scope, $element) {

      // Prepare the panel to be collapsible
      var $elem   = $($element),
          parent  = $elem.closest('.panel'), // find the first parent panel
          panelId = parent.attr('id');

      storage = $scope.$storage;

      // Load the saved state if exists
      var currentState = loadPanelState( panelId );
      if ( typeof currentState !== 'undefined') {
        $timeout(function(){
            $scope[panelId] = currentState; },
          10);
      }

      // bind events to switch icons
      $element.bind('click', function() {

        savePanelState( panelId, !$scope[panelId] );

      });
    }]
  };

  function savePanelState(id, state) {
    if(!id) return false;
    var data = angular.fromJson(storage[storageKeyName]);
    if(!data) { data = {}; }
    data[id] = state;
    storage[storageKeyName] = angular.toJson(data);
  }

  function loadPanelState(id) {
    if(!id) return false;
    var data = angular.fromJson(storage[storageKeyName]);
    if(data) {
      return data[id];
    }
  }

}])
/**=========================================================
 * Refresh panels
 * [panel-refresh] * [data-spinner="standard"]
 =========================================================*/
.directive('panelRefresh', ["$q", function($q){
  'use strict';
  
  return {
    restrict: 'A',
    scope: false,
    controller: ["$scope", "$element", function ($scope, $element) {
      
      var refreshEvent   = 'panel-refresh',
          whirlClass     = 'whirl',
          defaultSpinner = 'standard';


      // catch clicks to toggle panel refresh
      $element.on('click', function () {
        var $this   = $(this),
            panel   = $this.parents('.panel').eq(0),
            spinner = $this.data('spinner') || defaultSpinner
            ;

        // start showing the spinner
        panel.addClass(whirlClass + ' ' + spinner);

        // Emit event when refresh clicked
        $scope.$emit(refreshEvent, panel.attr('id'));

      });

      // listen to remove spinner
      $scope.$on('removeSpinner', removeSpinner);

      // method to clear the spinner when done
      function removeSpinner (ev, id) {
        if (!id) return;
        var newid = id.charAt(0) == '#' ? id : ('#'+id);
        angular
          .element(newid)
          .removeClass(whirlClass);
      }
    }]
  };
}]);

/**=========================================================
 * Module: play-animation.js
 * Provides a simple way to run animation with a trigger
 * Requires animo.js
 =========================================================*/
 
App.directive('animate', ["$window", "Utils", function($window, Utils){

  'use strict';

  var $scroller = $(window).add('body, .wrapper');
  
  return {
    restrict: 'A',
    link: function (scope, elem, attrs) {

      // Parse animations params and attach trigger to scroll
      var $elem     = $(elem),
          offset    = $elem.data('offset'),
          delay     = $elem.data('delay')     || 100, // milliseconds
          animation = $elem.data('play')      || 'bounce';
      
      if(typeof offset !== 'undefined') {
        
        // test if the element starts visible
        testAnimation($elem);
        // test on scroll
        $scroller.scroll(function(){
          testAnimation($elem);
        });

      }

      // Test an element visibilty and trigger the given animation
      function testAnimation(element) {
          if ( !element.hasClass('anim-running') &&
              Utils.isInView(element, {topoffset: offset})) {
          element
            .addClass('anim-running');

          setTimeout(function() {
            element
              .addClass('anim-done')
              .animo( { animation: animation, duration: 0.7} );
          }, delay);

        }
      }

      // Run click triggered animations
      $elem.on('click', function() {

        var $elem     = $(this),
            targetSel = $elem.data('target'),
            animation = $elem.data('play') || 'bounce',
            target    = $(targetSel);

        if(target && target.length) {
          target.animo( { animation: animation } );
        }
        
      });
    }
  };

}]);

/**=========================================================
 * Module: scroll.js
 * Make a content box scrollable
 =========================================================*/

App.directive('scrollable', function(){
  return {
    restrict: 'EA',
    link: function(scope, elem, attrs) {
      var defaultHeight = 250;
      elem.slimScroll({
          height: (attrs.height || defaultHeight)
      });
    }
  };
});
/**=========================================================
 * Module: sidebar.js
 * Wraps the sidebar and handles collapsed state
 =========================================================*/

App.directive('sidebar', ['$rootScope', '$window', 'Utils', function($rootScope, $window, Utils) {
  
  var $win  = $($window);
  var $body = $('body');
  var $scope;
  var $sidebar;
  var currentState = $rootScope.$state.current.name;

  return {
    restrict: 'EA',
    template: '<nav class="sidebar" ng-transclude></nav>',
    transclude: true,
    replace: true,
    link: function(scope, element, attrs) {
      
      $scope   = scope;
      $sidebar = element;

      var eventName = Utils.isTouch() ? 'click' : 'mouseenter' ;
      var subNav = $();
      $sidebar.on( eventName, '.nav > li', function() {

        if( Utils.isSidebarCollapsed() || $rootScope.app.layout.asideHover ) {

          subNav.trigger('mouseleave');
          subNav = toggleMenuItem( $(this) );

          // Used to detect click and touch events outside the sidebar          
          sidebarAddBackdrop();

        }

      });

      scope.$on('closeSidebarMenu', function() {
        removeFloatingNav();
      });

      // Normalize state when resize to mobile
      $win.on('resize', function() {
        if( ! Utils.isMobile() )
          $body.removeClass('aside-toggled');
      });

      // Adjustment on route changes
      $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
        currentState = toState.name;
        // Hide sidebar automatically on mobile
        $('body.aside-toggled').removeClass('aside-toggled');

        $rootScope.$broadcast('closeSidebarMenu');
      });

      // Allows to close
      if ( angular.isDefined(attrs.sidebarAnyclickClose) ) {

        $('.wrapper').on('click.sidebar', function(e){
          // don't check if sidebar not visible
          if( ! $body.hasClass('aside-toggled')) return;

          // if not child of sidebar
          if( ! $(e.target).parents('.aside').length ) {
            $body.removeClass('aside-toggled');          
          }

        });
      }

    }
  };

  function sidebarAddBackdrop() {
    var $backdrop = $('<div/>', { 'class': 'dropdown-backdrop'} );
    $backdrop.insertAfter('.aside-inner').on("click mouseenter", function () {
      removeFloatingNav();
    });
  }

  // Open the collapse sidebar submenu items when on touch devices 
  // - desktop only opens on hover
  function toggleTouchItem($element){
    $element
      .siblings('li')
      .removeClass('open')
      .end()
      .toggleClass('open');
  }

  // Handles hover to open items under collapsed menu
  // ----------------------------------- 
  function toggleMenuItem($listItem) {

    removeFloatingNav();

    var ul = $listItem.children('ul');
    
    if( !ul.length ) return $();
    if( $listItem.hasClass('open') ) {
      toggleTouchItem($listItem);
      return $();
    }

    var $aside = $('.aside');
    var $asideInner = $('.aside-inner'); // for top offset calculation
    // float aside uses extra padding on aside
    var mar = parseInt( $asideInner.css('padding-top'), 0) + parseInt( $aside.css('padding-top'), 0);
    var subNav = ul.clone().appendTo( $aside );
    
    toggleTouchItem($listItem);

    var itemTop = ($listItem.position().top + mar) - $sidebar.scrollTop();
    var vwHeight = $win.height();

    subNav
      .addClass('nav-floating')
      .css({
        position: $scope.app.layout.isFixed ? 'fixed' : 'absolute',
        top:      itemTop,
        bottom:   (subNav.outerHeight(true) + itemTop > vwHeight) ? 0 : 'auto'
      });

    subNav.on('mouseleave', function() {
      toggleTouchItem($listItem);
      subNav.remove();
    });

    return subNav;
  }

  function removeFloatingNav() {
    $('.dropdown-backdrop').remove();
    $('.sidebar-subnav.nav-floating').remove();
    $('.sidebar li.open').removeClass('open');
  }

}]);
/**=========================================================
 * Module: skycons.js
 * Include any animated weather icon from Skycons
 =========================================================*/

App.directive('skycon', function(){

  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      
      var skycons = new Skycons({'color': (attrs.color || 'white')});

      element.html('<canvas width="' + attrs.width + '" height="' + attrs.height + '"></canvas>');

      skycons.add(element.children()[0], attrs.skycon);

      skycons.play();

    }
  };
});
/**=========================================================
 * Module: sparkline.js
 * SparkLines Mini Charts
 =========================================================*/
 
App.directive('sparkline', ['$timeout', '$window', function($timeout, $window){

  'use strict';

  return {
    restrict: 'EA',
    controller: ["$scope", "$element", function ($scope, $element) {
      var runSL = function(){
        initSparLine($element);
      };

      $timeout(runSL);
    }]
  };

  function initSparLine($element) {
    var options = $element.data();

    options.type = options.type || 'bar'; // default chart is bar
    options.disableHiddenCheck = true;

    $element.sparkline('html', options);

    if(options.resize) {
      $(window).resize(function(){
        $element.sparkline('html', options);
      });
    }
  }

}]);

/**=========================================================
 * Module: table-checkall.js
 * Tables check all checkbox
 =========================================================*/

App.directive('checkAll', function() {
  'use strict';
  
  return {
    restrict: 'A',
    controller: ["$scope", "$element", function($scope, $element){
      
      $element.on('change', function() {
        var $this = $(this),
            index= $this.index() + 1,
            checkbox = $this.find('input[type="checkbox"]'),
            table = $this.parents('table');
        // Make sure to affect only the correct checkbox column
        table.find('tbody > tr > td:nth-child('+index+') input[type="checkbox"]')
          .prop('checked', checkbox[0].checked);

      });
    }]
  };

});
/**=========================================================
 * Module: tags-input.js
 * Initializes the tag inputs plugin
 =========================================================*/

App.directive('tagsinput', ["$timeout", function($timeout) {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {

      element.on('itemAdded itemRemoved', function(){
        // check if view value is not empty and is a string
        // and update the view from string to an array of tags
        if(ngModel.$viewValue && ngModel.$viewValue.split) {
          ngModel.$setViewValue( ngModel.$viewValue.split(',') );
          ngModel.$render();
        }
      });

      $timeout(function(){
        element.tagsinput();
      });

    }
  };
}]);

/**=========================================================
 * Module: toggle-state.js
 * Toggle a classname from the BODY Useful to change a state that 
 * affects globally the entire layout or more than one item 
 * Targeted elements must have [toggle-state="CLASS-NAME-TO-TOGGLE"]
 * User no-persist to avoid saving the sate in browser storage
 =========================================================*/

App.directive('toggleState', ['toggleStateService', function(toggle) {
  'use strict';
  
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {

      var $body = $('body');

      $(element)
        .on('click', function (e) {
          e.preventDefault();
          var classname = attrs.toggleState;
          
          if(classname) {
            if( $body.hasClass(classname) ) {
              $body.removeClass(classname);
              if( ! attrs.noPersist)
                toggle.removeState(classname);
            }
            else {
              $body.addClass(classname);
              if( ! attrs.noPersist)
                toggle.addState(classname);
            }
            
          }

      });
    }
  };
  
}]);

/**=========================================================
 * Module: trigger-resize.js
 * Triggers a window resize event from any element
 =========================================================*/

App.directive("triggerResize", ['$window', '$timeout', function ($window, $timeout) {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      element.on('click', function(){
        $timeout(function(){
          $window.dispatchEvent(new Event('resize'))
        });
      });
    }
  };
}]);

/**=========================================================
 * Module: validate-form.js
 * Initializes the validation plugin Parsley
 =========================================================*/

App.directive('validateForm', function() {
  return {
    restrict: 'A',
    controller: ["$scope", "$element", function($scope, $element) {
      var $elem = $($element);
      if($.fn.parsley)
        $elem.parsley();
    }]
  };
});  

/**=========================================================
 * Module: vector-map.js.js
 * Init jQuery Vector Map plugin
 =========================================================*/

App.directive('vectorMap', ['vectorMap', function(vectorMap){
  'use strict';

  var defaultColors = {
      markerColor:  '#23b7e5',      // the marker points
      bgColor:      'transparent',      // the background
      scaleColors:  ['#878c9a'],    // the color of the region in the serie
      regionFill:   '#bbbec6'       // the base region color
  };

  return {
    restrict: 'EA',
    link: function(scope, element, attrs) {

      var mapHeight   = attrs.height || '300',
          options     = {
            markerColor:  attrs.markerColor  || defaultColors.markerColor,
            bgColor:      attrs.bgColor      || defaultColors.bgColor,
            scale:        attrs.scale        || 1,
            scaleColors:  attrs.scaleColors  || defaultColors.scaleColors,
            regionFill:   attrs.regionFill   || defaultColors.regionFill,
            mapName:      attrs.mapName      || 'world_mill_en'
          };
      
      element.css('height', mapHeight);
      
      vectorMap.init( element , options, scope.seriesData, scope.markersData);

    }
  };

}]);
/**=========================================================
 * Module: browser.js
 * Browser detection
 =========================================================*/

App.service('browser', function(){
  "use strict";

  var matched, browser;

  var uaMatch = function( ua ) {
    ua = ua.toLowerCase();

    var match = /(opr)[\/]([\w.]+)/.exec( ua ) ||
      /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
      /(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) ||
      /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
      /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
      /(msie) ([\w.]+)/.exec( ua ) ||
      ua.indexOf("trident") >= 0 && /(rv)(?::| )([\w.]+)/.exec( ua ) ||
      ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
      [];

    var platform_match = /(ipad)/.exec( ua ) ||
      /(iphone)/.exec( ua ) ||
      /(android)/.exec( ua ) ||
      /(windows phone)/.exec( ua ) ||
      /(win)/.exec( ua ) ||
      /(mac)/.exec( ua ) ||
      /(linux)/.exec( ua ) ||
      /(cros)/i.exec( ua ) ||
      [];

    return {
      browser: match[ 3 ] || match[ 1 ] || "",
      version: match[ 2 ] || "0",
      platform: platform_match[ 0 ] || ""
    };
  };

  matched = uaMatch( window.navigator.userAgent );
  browser = {};

  if ( matched.browser ) {
    browser[ matched.browser ] = true;
    browser.version = matched.version;
    browser.versionNumber = parseInt(matched.version);
  }

  if ( matched.platform ) {
    browser[ matched.platform ] = true;
  }

  // These are all considered mobile platforms, meaning they run a mobile browser
  if ( browser.android || browser.ipad || browser.iphone || browser[ "windows phone" ] ) {
    browser.mobile = true;
  }

  // These are all considered desktop platforms, meaning they run a desktop browser
  if ( browser.cros || browser.mac || browser.linux || browser.win ) {
    browser.desktop = true;
  }

  // Chrome, Opera 15+ and Safari are webkit based browsers
  if ( browser.chrome || browser.opr || browser.safari ) {
    browser.webkit = true;
  }

  // IE11 has a new token so we will assign it msie to avoid breaking changes
  if ( browser.rv )
  {
    var ie = "msie";

    matched.browser = ie;
    browser[ie] = true;
  }

  // Opera 15+ are identified as opr
  if ( browser.opr )
  {
    var opera = "opera";

    matched.browser = opera;
    browser[opera] = true;
  }

  // Stock Android browsers are marked as Safari on Android.
  if ( browser.safari && browser.android )
  {
    var android = "android";

    matched.browser = android;
    browser[android] = true;
  }

  // Assign the name and platform variable
  browser.name = matched.browser;
  browser.platform = matched.platform;


  return browser;

});
/**=========================================================
 * Module: colors.js
 * Services to retrieve global colors
 =========================================================*/
 
App.factory('colors', ['APP_COLORS', function(colors) {
  
  return {
    byName: function(name) {
      return (colors[name] || '#fff');
    }
  };

}]);
App.factory('ContextMenuService', function() {
    return {
      element: null,
      menuElement: null
    };
});
/**=========================================================
 * Module: nav-search.js
 * Services to share navbar search functions
 =========================================================*/
 
App.service('navSearch', function() {
  var navbarFormSelector = 'form.navbar-form';
  return {
    toggle: function() {
      
      var navbarForm = $(navbarFormSelector);

      navbarForm.toggleClass('open');
      
      var isOpen = navbarForm.hasClass('open');
      
      navbarForm.find('input')[isOpen ? 'focus' : 'blur']();

    },

    dismiss: function() {
      $(navbarFormSelector)
        .removeClass('open')      // Close control
        .find('input[type="text"]').blur() // remove focus
        .val('')                    // Empty input
        ;
    }
  };

});
/**=========================================================
 * Module: notify.js
 * Create a notifications that fade out automatically.
 * Based on Notify addon from UIKit (http://getuikit.com/docs/addons_notify.html)
 =========================================================*/

App.service('Notify', ["$timeout", function($timeout){
    this.alert = alert;

    ////////////////

    function alert(msg, opts) {
        if ( msg ) {
            $timeout(function(){
                $.notify(msg, opts || {});
            });
        }
    }

}]);



/**
 * Notify Addon definition as jQuery plugin
 * Adapted version to work with Bootstrap classes
 * More information http://getuikit.com/docs/addons_notify.html
 */

(function($, window, document){

    var containers = {},
        messages   = {},

        notify     =  function(options){

            if ($.type(options) == 'string') {
                options = { message: options };
            }

            if (arguments[1]) {
                options = $.extend(options, $.type(arguments[1]) == 'string' ? {status:arguments[1]} : arguments[1]);
            }

            return (new Message(options)).show();
        },
        closeAll  = function(group, instantly){
            if(group) {
                for(var id in messages) { if(group===messages[id].group) messages[id].close(instantly); }
            } else {
                for(var id in messages) { messages[id].close(instantly); }
            }
        };

    var Message = function(options){

        var $this = this;

        this.options = $.extend({}, Message.defaults, options);

        this.uuid    = "ID"+(new Date().getTime())+"RAND"+(Math.ceil(Math.random() * 100000));
        this.element = $([
            // @geedmo: alert-dismissable enables bs close icon
            '<div class="uk-notify-message alert-dismissable">',
                '<a class="close">&times;</a>',
                '<div>'+this.options.message+'</div>',
            '</div>'

        ].join('')).data("notifyMessage", this);

        // status
        if (this.options.status) {
            this.element.addClass('alert alert-'+this.options.status);
            this.currentstatus = this.options.status;
        }

        this.group = this.options.group;

        messages[this.uuid] = this;

        if(!containers[this.options.pos]) {
            containers[this.options.pos] = $('<div class="uk-notify uk-notify-'+this.options.pos+'"></div>').appendTo('body').on("click", ".uk-notify-message", function(){
                $(this).data("notifyMessage").close();
            });
        }
    };


    $.extend(Message.prototype, {

        uuid: false,
        element: false,
        timout: false,
        currentstatus: "",
        group: false,

        show: function() {

            if (this.element.is(":visible")) return;

            var $this = this;

            containers[this.options.pos].show().prepend(this.element);

            var marginbottom = parseInt(this.element.css("margin-bottom"), 10);

            this.element.css({"opacity":0, "margin-top": -1*this.element.outerHeight(), "margin-bottom":0}).animate({"opacity":1, "margin-top": 0, "margin-bottom":marginbottom}, function(){

                if ($this.options.timeout) {

                    var closefn = function(){ $this.close(); };

                    $this.timeout = setTimeout(closefn, $this.options.timeout);

                    $this.element.hover(
                        function() { clearTimeout($this.timeout); },
                        function() { $this.timeout = setTimeout(closefn, $this.options.timeout);  }
                    );
                }

            });

            return this;
        },

        close: function(instantly) {

            var $this    = this,
                finalize = function(){
                    $this.element.remove();

                    if(!containers[$this.options.pos].children().length) {
                        containers[$this.options.pos].hide();
                    }

                    delete messages[$this.uuid];
                };

            if(this.timeout) clearTimeout(this.timeout);

            if(instantly) {
                finalize();
            } else {
                this.element.animate({"opacity":0, "margin-top": -1* this.element.outerHeight(), "margin-bottom":0}, function(){
                    finalize();
                });
            }
        },

        content: function(html){

            var container = this.element.find(">div");

            if(!html) {
                return container.html();
            }

            container.html(html);

            return this;
        },

        status: function(status) {

            if(!status) {
                return this.currentstatus;
            }

            this.element.removeClass('alert alert-'+this.currentstatus).addClass('alert alert-'+status);

            this.currentstatus = status;

            return this;
        }
    });

    Message.defaults = {
        message: "",
        status: "normal",
        timeout: 5000,
        group: null,
        pos: 'top-center'
    };


    $["notify"]          = notify;
    $["notify"].message  = Message;
    $["notify"].closeAll = closeAll;

    return notify;

}(jQuery, window, document));

/**=========================================================
 * Module: helpers.js
 * Provides helper functions for routes definition
 =========================================================*/

App.provider('RouteHelpers', ['APP_REQUIRES', function (appRequires) {
  "use strict";

  // Set here the base of the relative path
  // for all app views
  this.basepath = function (uri) {
    return 'app/views/' + uri;
  };

  // Generates a resolve object by passing script names
  // previously configured in constant.APP_REQUIRES
  this.resolveFor = function () {
    var _args = arguments;
    return {
      deps: ['$ocLazyLoad','$q', function ($ocLL, $q) {
        // Creates a promise chain for each argument
        var promise = $q.when(1); // empty promise
        for(var i=0, len=_args.length; i < len; i ++){
          promise = andThen(_args[i]);
        }
        return promise;

        // creates promise to chain dynamically
        function andThen(_arg) {
          // also support a function that returns a promise
          if(typeof _arg == 'function')
              return promise.then(_arg);
          else
              return promise.then(function() {
                // if is a module, pass the name. If not, pass the array
                var whatToLoad = getRequired(_arg);
                // simple error check
                if(!whatToLoad) return $.error('Route resolve: Bad resource name [' + _arg + ']');
                // finally, return a promise
                return $ocLL.load( whatToLoad );
              });
        }
        // check and returns required data
        // analyze module items with the form [name: '', files: []]
        // and also simple array of script files (for not angular js)
        function getRequired(name) {
          if (appRequires.modules)
              for(var m in appRequires.modules)
                  if(appRequires.modules[m].name && appRequires.modules[m].name === name)
                      return appRequires.modules[m];
          return appRequires.scripts && appRequires.scripts[name];
        }

      }]};
  }; // resolveFor

  // not necessary, only used in config block for routes
  this.$get = function(){
    return {
      basepath: this.basepath
    }
  };

}]);


/**=========================================================
 * Module: toggle-state.js
 * Services to share toggle state functionality
 =========================================================*/

App.service('toggleStateService', ['$rootScope', function($rootScope) {

  var storageKeyName  = 'toggleState';

  // Helper object to check for words in a phrase //
  var WordChecker = {
    hasWord: function (phrase, word) {
      return new RegExp('(^|\\s)' + word + '(\\s|$)').test(phrase);
    },
    addWord: function (phrase, word) {
      if (!this.hasWord(phrase, word)) {
        return (phrase + (phrase ? ' ' : '') + word);
      }
    },
    removeWord: function (phrase, word) {
      if (this.hasWord(phrase, word)) {
        return phrase.replace(new RegExp('(^|\\s)*' + word + '(\\s|$)*', 'g'), '');
      }
    }
  };

  // Return service public methods
  return {
    // Add a state to the browser storage to be restored later
    addState: function(classname){
      var data = angular.fromJson($rootScope.$storage[storageKeyName]);
      
      if(!data)  {
        data = classname;
      }
      else {
        data = WordChecker.addWord(data, classname);
      }

      $rootScope.$storage[storageKeyName] = angular.toJson(data);
    },

    // Remove a state from the browser storage
    removeState: function(classname){
      var data = $rootScope.$storage[storageKeyName];
      // nothing to remove
      if(!data) return;

      data = WordChecker.removeWord(data, classname);

      $rootScope.$storage[storageKeyName] = angular.toJson(data);
    },
    
    // Load the state string and restore the classlist
    restoreState: function($elem) {
      var data = angular.fromJson($rootScope.$storage[storageKeyName]);
      
      // nothing to restore
      if(!data) return;
      $elem.addClass(data);
    }

  };

}]);
/**=========================================================
 * Module: utils.js
 * Utility library to use across the theme
 =========================================================*/

App.service('Utils', ["$window", "APP_MEDIAQUERY", function($window, APP_MEDIAQUERY) {
    'use strict';
    
    var $html = angular.element("html"),
        $win  = angular.element($window),
        $body = angular.element('body');

    return {
      // DETECTION
      support: {
        transition: (function() {
                var transitionEnd = (function() {

                    var element = document.body || document.documentElement,
                        transEndEventNames = {
                            WebkitTransition: 'webkitTransitionEnd',
                            MozTransition: 'transitionend',
                            OTransition: 'oTransitionEnd otransitionend',
                            transition: 'transitionend'
                        }, name;

                    for (name in transEndEventNames) {
                        if (element.style[name] !== undefined) return transEndEventNames[name];
                    }
                }());

                return transitionEnd && { end: transitionEnd };
            })(),
        animation: (function() {

            var animationEnd = (function() {

                var element = document.body || document.documentElement,
                    animEndEventNames = {
                        WebkitAnimation: 'webkitAnimationEnd',
                        MozAnimation: 'animationend',
                        OAnimation: 'oAnimationEnd oanimationend',
                        animation: 'animationend'
                    }, name;

                for (name in animEndEventNames) {
                    if (element.style[name] !== undefined) return animEndEventNames[name];
                }
            }());

            return animationEnd && { end: animationEnd };
        })(),
        requestAnimationFrame: window.requestAnimationFrame ||
                               window.webkitRequestAnimationFrame ||
                               window.mozRequestAnimationFrame ||
                               window.msRequestAnimationFrame ||
                               window.oRequestAnimationFrame ||
                               function(callback){ window.setTimeout(callback, 1000/60); },
        touch: (
            ('ontouchstart' in window && navigator.userAgent.toLowerCase().match(/mobile|tablet/)) ||
            (window.DocumentTouch && document instanceof window.DocumentTouch)  ||
            (window.navigator['msPointerEnabled'] && window.navigator['msMaxTouchPoints'] > 0) || //IE 10
            (window.navigator['pointerEnabled'] && window.navigator['maxTouchPoints'] > 0) || //IE >=11
            false
        ),
        mutationobserver: (window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver || null)
      },
      // UTILITIES
      isInView: function(element, options) {

          var $element = $(element);

          if (!$element.is(':visible')) {
              return false;
          }

          var window_left = $win.scrollLeft(),
              window_top  = $win.scrollTop(),
              offset      = $element.offset(),
              left        = offset.left,
              top         = offset.top;

          options = $.extend({topoffset:0, leftoffset:0}, options);

          if (top + $element.height() >= window_top && top - options.topoffset <= window_top + $win.height() &&
              left + $element.width() >= window_left && left - options.leftoffset <= window_left + $win.width()) {
            return true;
          } else {
            return false;
          }
      },
      langdirection: $html.attr("dir") == "rtl" ? "right" : "left",
      isTouch: function () {
        return $html.hasClass('touch');
      },
      isSidebarCollapsed: function () {
        return $body.hasClass('aside-collapsed');
      },
      isSidebarToggled: function () {
        return $body.hasClass('aside-toggled');
      },
      isMobile: function () {
        return $win.width() < APP_MEDIAQUERY.tablet;
      }
    };
}]);
/**=========================================================
 * Module: vector-map.js
 * Services to initialize vector map plugin
 =========================================================*/

App.service('vectorMap', function() {
  'use strict';
  return {
    init: function($element, opts, series, markers) {
          $element.vectorMap({
            map:             opts.mapName,
            backgroundColor: opts.bgColor,
            zoomMin:         1,
            zoomMax:         8,
            zoomOnScroll:    false,
            regionStyle: {
              initial: {
                'fill':           opts.regionFill,
                'fill-opacity':   1,
                'stroke':         'none',
                'stroke-width':   1.5,
                'stroke-opacity': 1
              },
              hover: {
                'fill-opacity': 0.8
              },
              selected: {
                fill: 'blue'
              },
              selectedHover: {
              }
            },
            focusOn:{ x:0.4, y:0.6, scale: opts.scale},
            markerStyle: {
              initial: {
                fill: opts.markerColor,
                stroke: opts.markerColor
              }
            },
            onRegionLabelShow: function(e, el, code) {
              if ( series && series[code] )
                el.html(el.html() + ': ' + series[code] + ' visitors');
            },
            markers: markers,
            series: {
                regions: [{
                    values: series,
                    scale: opts.scaleColors,
                    normalizeFunction: 'polynomial'
                }]
            },
          });
        }
  };
});
// To run this code, edit file 
// index.html or index.jade and change
// html data-ng-app attribute from
// angle to myAppName
// ----------------------------------- 

var myApp = angular.module('myAppName', ['angle']);

myApp.run(["$log", function($log) {

  $log.log('I\'m a line from custom.js');

}]);

myApp.config(["RouteHelpersProvider", function(RouteHelpersProvider) {

  // Custom Route definition
  
}]);

myApp.controller('oneOfMyOwnController', ["$scope", function($scope) {
  /* controller code */
}]);

myApp.directive('oneOfMyOwnDirectives', function() {
  /*directive code*/
});

myApp.config(["$stateProvider", function($stateProvider /* ... */) {
  /* specific routes here (see file config.js) */
}]);